React pagination
Pagination করার জন্য অনেক থার্ড পার্টি লাইব্রেরি পাবেন গুগল করলেই। তবে আজকে আমি দেখাব কিভাবে কোন থার্ড পার্টি লাইব্রেরি ছাড়াই pagination করতে পারবেন শুধুমাত্র javascript এর মাধ্যমে।
Pagination কি ?
যখন আপনার ওয়েবসাইটে অসংখ্য ডাটা থাকবে সেগুলো কে এক পেইজে সবগুলো না দেখিয়ে আলাদা পেইজে নিদৃষ্ট সংখ্যক ডাটা দেখানোই হচ্ছে Pagination.
শুরু করা যাক:
কাজের সুবিধার্থে শুরুতেই Jsonplaceholder থেকে ১০০ পোস্ট নিয়ে নিলাম। এখন আমরা চাইলে ১০০ পোস্ট একপেইজেই দেখাতে পারি সেটা আমাদের pagination এর লক্ষনা। আমরা চাই প্রত্যেক পেইজে যেন ১০টা করে পোস্ট থাকে। এই কাজটা আমরা pagination এর মাধ্যমে খুব সহজেই করে ফেলতে পারি।
আচ্ছা, শুরুতে pagination এর কথা ভুলে যান। আমারা যদি একশত ডাটা থেকে দশটা ডাটা দেখাতে চাই তবে কি করতে হবে?
সিম্পল কাজ একশত ডাটাকে ম্যাপ না করে স্লাইস করে দশটা ডাটা নিয়ে (০, ১০) পর্যন্ত সেগুলোকে ম্যাপ করে দিব। এখন আপনি চাইলে আপনার পেইজ রিলোড করে দেখতে পারেন ১০ টা ডাটা দেখাচ্ছে। এবার আমরা যদি পরবর্তী দশটা ডাটা দেখাতে চাই তবে স্লাইস করব (১০, ২০) পর্যন্ত, পরবর্তীতে স্লাইস করব (২০, ৩০) পর্যন্ত এভাবে আগাব সামনের দিকে। এখন কথাহচ্ছে আমরা যদি হার্ডকোডেড স্লাইস করি তবে দেখতে পাব প্রত্যেক বার সেইম ডাটা থাকছে। কিন্তু আমরাতো এইটা চাচ্ছিনা। তো কি করতে পারি?
আমরা ডায়নামিক ভাবে স্লাইস করতে পারি। যেমনঃ
এখানে start এবং end এর মান ডায়নামিক ভাবে পরিবর্তন করব। এই কাজটা করার জন্য আমরা হুক কল করতে পারি যেখানে start এবং end এর মান সেট করব।
এবার আমরা স্লাইস করব
আমরা চাইলে আরএক্টু গুছিয়ে নিতেপারি distructure এর মাধ্যমে,
আমি কোডটা আরেকটু গুছিয়ে নিচ্ছি আপনারা চাইলে এই কাজটা স্কিপ করতে পারেন।
এখন আমরা end এর জায়গায় itemsPerPage দিয়ে দিব।
খন একটা কম্পনেন্ট তৈরি করে নিচ্ছি, আপনারা চাইলে সেইম কম্পনেন্টেই পরবর্তী কাজগুলো করতে পারেন। তবে আমি প্রেফার করব নতুন কম্পনেন্টে পরবর্তী কাজগুলো করতে তাহলে কোড গুলো গোছালো থাকবে।
তো আমি একটা কম্পনেন্ট তৈরি করলাম paginationWithPreviousNextBtn.js নামে। যেখানে শুরুতে পরবর্তী পেইজে যাওয়ার জন্য Next এবং পূর্ববর্তী পেইজে যাওয়ার জন্য Previous নামে দুইটা বাটন তৈরি করে নিলাম।
এবার paginationWithPreviousNextBtn.js কম্পনেন্ট App.js কম্পনেন্টে import করে itemsPerPage প্রপস আকারে পাঠিয়ে দিলাম।
এখন paginationWithPreviousNextBtn.js এ একটা counter হুক তৈরি করে নিব, যার উপর ভিত্তি করে আমাদের pagination কাজ করবে। শুরুতে counter এর মান হবে 1
এখন Next বাটনে ক্লিক করলে কাউন্টারের মান বাড়বে এবং Previous বাটনে ক্লিক করলে কাউন্টারের মান কমবে। এটা করার জন্য Next এবং Previous বাটনে onClick ফাংশন দিয়ে দিতে পারি।
এখন আপনারা চাইলে, ইন্সপেক্ট করে React dev tool এক্সটেনশন এর মাধ্যমে দেখতে পারেন paginationWithPreviousNextBtn কম্পনেন্টে এর মধ্যে হুক-এ থাকা state এর মান Next বাটনে ক্লিক করলে বাড়বে এবং Previous বাটনে ক্লিক করলে কমবে। কিন্তু এখানে একটা ছোট প্রব্লেম আছে, Previous বাটনে ক্লিক করলে একসময় নেগেটিভ মান চলে আসে। আপাতত এইটা নিয়ে চিন্তার কিছু নাই, পরে এইটা ফিক্স করে ফলব।
এখন, যেহেতু কাউন্টারের মানের উপর ভিত্তি করে আমরা সব কাজ করব তার জন্য counter এর মান কখন বাড়ছে বা কমছে সেইটা ডিটেক্ট করতে হবে। এখন এই কাজটা useEffect হুক এর মাধ্যমে করে ফলতে পারি। সিম্পলি useEffect হুক এর ডিপেন্ডেন্সি দিয়ে দিব counter
এর মানে হচ্ছে, যখন counter এর মান পরিবর্তন হবে তখনই হুক কাজ করবে।
এখন কাজ হচ্ছে, counter এর মান বাড়লে বা কমলে itemsPerPage এর মানের উপর ভিত্তি করে start এবং end এর মান বাড়বে বা কমবে। কাজটা অনেকভাবেই করাযায়, আমি একভাবে দেখাচ্ছি আপনি চাইলে ভিন্নভাবেও করতে পারেন এবং কিভাবে কাজ হিচ্ছে console.log করতে পারেন শুরুতে।
এখন আমরা তো itemsPerPage এর অনুপাতে মান বাড়াতে বা কমাতে পারছি। এখন কোন ভাবে যদি এই মানটা slice এর start এবং end পর্যন্ত পাঠাতে পারি তাহলেই কাজ শেষ।
তো আমরা child component থেকে parent component এ এই মানটা অনেক ভাবেই পাঠাতে পারি। আমি সহজ ভাবে parent component এ একটা ফাংশন তৈরি করে props আকারে পাঠিয়ে দিচ্ছি। আপনি চাইলে context api বা অন্য ভাবেও পাঠাতে পারেন।
এখন, parent কম্পনেন্টে একটা ফাংশন তৈরি করে সেটাকে props হিসাবে চাইল্ড কম্পনেন্টে পাঠিয়ে দিব এবং সেখান থকে কল করব।
এখন parent ককম্পনেন্টে,
বুঝার সুবিধার্থে শুরুতে console.log করে রাখলাম।
এবার, paginationWithPreviousNextBtn কম্পনেন্টে আগে থেকেই props হিসাবে পাঠিয়ে দেওয়া itemsPerPage এর সাথে onPaginationChange-ও পাঠিয়ে দিব
এখন, paginationWithPreviousNextBtn কম্পনেন্ট থেকে onPaginationChange, props রিসিভ করে distructure করে useEffect হুক থেকে কল করব।
বার আপনি console এ দেখতে পারবেন Next অথবা Previous বাটনে ক্লিক করলে value বাড়ছে বা কমছে। এখন setPagination এ start এবং end value সেট করে দিলেই কাজ শেষ।
এখন ব্রাউজারে দেখবেন pagination কাজ হচ্ছে, কিন্তু একটা সমস্যা রয়েগেছে, সর্বশেষ ডাটা এর পরও Next এবং শুরুতে Previous বাটনে ক্লিক করলে ব্ল্যাংক পেইজ আসতেছে। এবার এইটা ফিক্স করার পালা। এখন আমরা এটা ফিক্স করতে পারি খুব সহজে একটা কন্ডিশন এর মাধ্যমে, আমরা যেখানে onClick এর মধ্যে সরাসরি counter সেট করে দিচ্ছিলাম এখন সেটার পরিবর্তে onClick এ একটা ফাংশন দিব এবং ডিটেক্ট করব কোন বাটনে ক্লিক করা হয়েছে তারপর ফাংশন এর মধ্যে condition দিব।
এবার, ফাংশন:
এখানে totalItems হচ্ছে যেই item বা data গুলোকে pagination করছি সেটার লেংথ। এটাকে parent কম্পনেন্ট থেকে props আকারে নিয়েছি।
ফাইনাল কোড: Github, CodeSandbox
Pagination এর আরেকটা সিস্টেম রয়েছে সেটায় Next / Previous বাটনের পাশাপাশি প্রত্যেক পেইজের জন্য আলাদা ভাবে পেইজ নাম্বার থাকে। সেটাও এইটার সাথে ৯০% সিমিলার। আপনি চাইলে আমার GitHub / CodeSandboxথেকে সেই কোডও দেখতে পারেন।