রিয়েক্ট-রিডাক্স — দ্য ত্রাস

Solaiman Shadin
8 min readMay 13, 2021

আস্সালামুলাইকুম, আমি সোলাইমান স্বাধীন…

আজকের আর্টিকেলটি রিয়েক্ট-রিডাক্স নিয়ে।

এই আর্টিকেল এর মূল উদ্দেশ্য রিডাক্স নামক ত্রাসকে সহজ করা এবং রিডাক্স যে আসলে কঠিন কিছু না, তা প্রমাণ করা। সত্যি বলতে রিডাক্স আসলে ততটা জটিল না, যতটা আমরা মনে করি।

তাহলে,

রিডাক্স আসলে কী?

আসলে রিডাক্স একটি স্টেট ম্যানেজমেন্ট টুল ছাড়া আর কিছু না। আপনার এপ্লিকেশন এর স্টেট গুলা গ্লোবালি ম্যানেজ করার একটি টুল বলতে পারেন। যদি রিয়েক্ট-এর প্রেক্ষিতে চিন্তা করা হয়, কোন রিয়েক্ট কম্পনেন্ট এ যখন স্টেট ডিক্লেয়ার করা হয়, সেই স্টেট এর স্কোপ বা দৌড়ত্ব কিন্তু ওই কম্পনেন্ট পর্যন্তই। হ্যাঁ, এক কম্পনেন্ট থেকে আরেক কম্পনেন্ট-এ স্টেট এর ডেটা শেয়ার করতে পারি। সেটা কীভাবে? props আকারে প্যারেন্ট কম্পনেন্ট থেকে চাইল্ড কম্পোনেন্ট-এ পাস করে। যেই কম্পনেন্ট এ ডেটা পাস করতে চাচ্ছেন, সম্পর্কটা যদি চাইল্ড প্যারেন্ট না হয়? ডিরেক্ট চাইল্ড না হয়ে চাইল্ড এর চাইল্ড বা সেই চাইল্ড এর কোন এক পর্যায়ের চাইল্ড, তখন কি করবেন? props আকারে একটার পর একটারে দিতে থাকবেন! হতে পারে এইভাবে ১০ টা কম্পোনেন্ট-এ props ড্রিলিং করার পর, টার্গেট কম্পোনেন্ট পর্যন্ত ডেটা পাঠাতে পারলেন। এবার এমনও হতে পারে, যে কম্পনেন্ট থেকে অন্য কম্পনেন্ট-এ ডেটা পাস করবেন সেটার সাথে এইরকম ১০ লেভেল পরের গ্র‍্যান্ড চাইল্ড :) প্যারেন্ট সম্পর্কও নাই, ২ টা একদম ইন্ডিভিজুয়াল বা সম্পর্ক ছাড়া কম্পনেন্ট। তখন কী করবেন? এই দুইটা কম্পনেন্ট-এর কমন বাপ, সরি কমন প্যারেন্টকে খুঁজতে থাকবেন। খুঁজে পাওয়ার পর কী করবেন? আপনার সেই স্টেটটা Cut করে নিয়েএসে সেই কমন প্যারেন্ট এ সেট করে দিবেন! তারপর Props Props করে কম্পনেন্ট গুলাতে শেয়ার করবেন… এভাবে কত? এইটা আসলেই একটা প্রবলেম। এই পরিস্থিতিতে মাথায় আসতে পারে, ইশ্ জাভাস্ক্রিপ্ট-এর গ্লোবাল ভেরিএবল এর মত এই স্টেটগুলাও যদি গ্লোবালি ডিক্লেয়ার করতে পারতাম তাহলে এই বিষয় গুলা ম্যানেজ করতে সুবিধা হতো। তাই না? যখন যেখানে যেই ডেটা দরকার পরতো, সেই গ্লোবাল প্লেস থেকে ধাম করে সেখানে সেটা নিয়ে নিতাম। হ্যাঁ, আসলে রিডাক্স সেই কাজটাই করে আপনার জন্য। আপনার স্টেট গুলা গ্লোবালি ম্যানেজ করতে দেয়, হ্যা, এই যুগে Context API ও একইভাবে প্রবলেমের সমাধান করে, কিন্তু দেশের সফটওয়ার কোম্পানিগুলার রিকোয়ারমেন্ট বলেন বা লার্জ স্কেল এপ্লিকেশন যেখানে ইতোমধ্যে রিডাক্স ব্যবহার করা হয়েছে সেখানে টিকার জন্য বলেন, আমরা রিডাক্স শিখবো। আর হ্যাঁ, এখানে উদাহরণটা রিয়েক্ট কম্পনেন্ট দিয়ে টানা হলো বলে এই না যে রিডাক্স শুধুমাত্র রিয়েক্টের সম্পত্তি। না, রিডাক্স আসলে ইউনিভার্সাল একটা টুল। এইটা ভ্যানিলা জাভাস্ক্রিপ্ট থেকে শুরু করে অন্যান্য ফ্রন্টেড ফ্রেমওয়ার্ক Vue, Angular এও ব্যবহার করতে পারেন। আপনাকে শুধু রিডাক্স এর সিম্পল ইকোসিস্টেমটা বুঝতে হবে, আমরা ওল্ড স্কুল (Old School) ওয়েতেই সেটা বুঝে ফেলবো , শুধু তিনটা কোর জিনিসের মাধ্যমে- ১।স্টোর। ২। একশন। এবং ৩। রিডুউসার।

আচ্ছা, নিচের ছবিটি দিয়ে শুরু করা যাক।

স্টোর-

হ্যাঁ, এইখানে যে দেখতে পারতেছেন স্টোর নামের একটা জিনিস, যেটা রিডাক্স-এর কোর এলিমেন্টের একটা । আমাদের আশেপাশের সুপার শপ, বুক স্টোর বা দোকানের মতই। দোকানে কী থাকে? জিনিসপত্র গুলা স্টোর করা থাকে বিক্রির জন্য। তাই না? হ্যাঁ, ওইরকম একটা স্টোর রিডাক্স এ থাকবে। যেখানে আমাদের স্টেটগুলো স্টোর করা থাকবে, সেখান থেকে নিয়ে কাজ করবো। হ্যাঁ, গ্লোবাল প্লেস এটাই।

তারপর কি আসে?

একশন-

আপনার যদি একটা স্টোর বা দোকান থাকে সেইটা তো আর শুধু শোপিস এর মত ফেলে রেখে আপনার কোন লাভ হবে না, তাই না? দোকানে কিছু কাজ কারবার যেমন, কাঁচামাল ইমপোর্ট করা, একেক দরে একেক মালামাল সেল করার মত কিছু একশন বা কাজ থাকবে তো। থাকবে না? একশন‌! রিডাক্স-এ কাজ বা একশন হচ্ছে এইসব কি কি কাজ কারবার আপনার দোকান বা স্টোরে হতে পারে, সেটার একটি তালিকা বা লিস্ট বইকি আর কিছু না।

তারপর বেচারা…

রিডিউসার-

দোকান আছে, দোকানে কি কি কাজ কারবার হবে সবকিছুর লিস্ট আছে, ভালোই! কিন্তু এই action-গুলো নেয়া এবং দোকান-টা দেখাশোনা করার জন্য মিনিমাম একজন লোক একজন দোকানদার/সেলসম্যান কি লাগবেনা? আর আপনার দোকান বড় হলে অনেকগুলো দোকানদার থাকতেই পারে, স্বাভাবিক। হ্যাঁ, রিডিউসার হচ্ছে আপনার রিডাক্স স্টোর-এর দোকানদার বা সেলসম্যান। একেকটা রিডিউসার কি করবে! তার জন্য যে অ্যাকশনগুলো আছে সেগুলো পারফর্ম করবে সাথে একশন গুলোর পর আপনার স্টোর বা স্টেটের খেয়ালও রাখবে। যেমন, তার একটা কাজ আপনার দোকানের আপেল বিক্রি করা। একটি আপেল সে সেল করবে। সেল করার পর কয়টা আপেল আপনার দোকানে থাকলো বা আপনার সর্বমোট রেভিনিউ কত হলো সেগুলো সে হিসাব রাখবে।

কঠিন কিন্তু কিছু না। শুধু এই তিনটা জিনিস বুঝে থাকলে কংগ্রাচুলেশন আপনাকে। আপনি আসলে রিডাক্স বুঝে গেছেন।

এখন শুধু এই জিনিসগুলোর এক এক করে স্যাম্পল দেখার পালা…

So, আপনার রিয়্যাক্ট প্রজেক্ট-এ redux ইন্সটল করেন, সাথে react-redux : npm i redux react-redux . react-redux হচ্ছে আপনার রিয়েক্ট প্রযেক্টে অন্যান্য হুক এর মত হুক বেস্ড ওয়েতে redux নিয়ে কাজ করার জন্য একটা লাইব্রেরী । এখন আমরা যেটা করতে পারি, আমাদের জানা তিনটা জিনিস: স্টোর, একশন, রিডিউসার এগুলো রাখার জন্য ফোল্ডার করে নিয়ে কাজ শুরু করে দিতে পারি…

একশন থেকে শুরু,

যেমন আমাদের একটা গ্রোসারি শপ আছে। যেটার একশনগুলো আমরা নির্ধারণ করে রাখতে চাচ্ছি। একেক ধরনের একশন রাখার জন্য আলাদা আলাদা ফাইল করে নেয়া যেতে পারে। যেমন, আমাদের দোকানের Fruits ম্যানেজ করার জন্য একশন লিখব। আমাদের একশন ফোল্ডারে ওইটার জন্য fruitAction.js নামে ফাইল করে কাজ শুরু করতে পারি।

একশন গুলো রিডাক্স এর জন্য এক একটি অবজেক্ট বৈকি আর কিছু না।

একেকটা যে ইউনিক একশন সেটা আইডেন্টিফাই করার জন্য প্রতিটা অ্যাকশনে ‘type’ নামের একটা প্রোপার্টি মাস্ট রাখতেছি যেটা দিয়ে আমরা আমাদের একএকটা একশনকে আইডেন্টিফাই করতে পারব । এখন আপনার একশন অবজেক্টে আপনি আরও প্রপার্টি ঢুকাতেই পারেন। যেমন আমাদের গ্রোসারি শপ এর দুইটা একশন ফ্রুট বিক্রি করা (SELL_FRUIT) আর ফ্রুট ইমপোর্ট করা (IMPORT_FRUIT) । একশন দুটাতে আরো প্রোপার্টি থাকতে পারে যেমন SELL_FRUIT action এ কোন fruit-টি বিক্রি হইতেছে সেটার আইডি বা একসাথে যদি অনেকগুলো সেল করার একশন থাকে তাহলে fruits array, এর জন্য অবজেক্ট এর আরেকটা প্রোপার্টি থাকতে পারে। ফ্রুট ইমপোর্ট এর ক্ষেত্রেও Same, কি কি ফ্রুট ইমপোর্ট করবে সেটার একটা array নেয়ার জন্য ‘input’ নামের আরেকটি প্রোপার্টি অ্যাড করে দিচ্ছি। আপনার আরও ইনফর্মেশন রাখা লাগলে আপনি আরো প্রোপার্টি রাখবেন কিন্তু একটা কমন প্রোপার্টি মাস্ট রাখতে হবে যেটা দিয়ে আপনি এক একটা অ্যাকশনকে আইডেন্টিফাই করবেন। By convention, এই কমন প্রোপার্টি এর নাম ‘type’-ঐ রাখা হয় । ধারুম ধুরুম দুইটা একশন লিখে ফেলা শেষ। এই একশন গুলো আমাদের এপ্লিকেশনে ঘটবে। এক এক সময় এক এক জায়গা থেকে যেহেতু এই একশন গুলো ব্যবহার করা হবে তাই, Better, একশন গুলো দিয়ে ফাংশন তৈরি করে রাখা, ফাংশন আমরা যে কারণে ডিফাইন করি! একই কাজ বারবার করার জন্য একঐ কোড যাতে বার বার না লেখা লাগে, কোডগুলো দিয়ে ফাংশন বানিয়ে জাস্ট যখন যেখানে দরকার কল করে দিলেই হল।

এই টাইপের ফাংশনকে একশন হেল্পার ফাংশন বলা হয়ে থাকে। আমরা আসলে ফাংশন এর মধ্যে একশনটা লিখে রাখতেছি কারণ যখন এই ফাংশনটা কল করব তখন, সেই অ্যাকশনটাই রিটার্ন করবে। বারবার সব জায়গায় একশন অবজেক্টটা লেখা লাগবে না আর কি। আর ফাংশন যেহেতু বানাচ্ছি ডায়নামিক ভাবে ইনপুট দেয়ার জন্য লাগলে ফাংশনের প্যারামিটার ও ডিফাইন করে রাখতে পারি অ্যাকশন এর কোন প্রপার্টি-এর ভ্যালু হিসেবে পাস করার জন্য। Simply জাস্ট এগুলারে এক্সপোর্ট করে দিলেই এরা যেখানে দরকার পড়বে সেখানে এসে কাজ করতে রেডি।

এরপর রিডিউসার: একশন তো ডিফাইন করা হলো। একশন গুলো যে নিবে, দোকানদার বা সেলসম্যান বা রিডাক্স এর রিডিউসার এখন ডিফাইন করা যাক। যে কিনা একশন গুলো হ্যান্ডেল করবে।

কিছুনা আবারও ফাংশন। আমাদের গ্রোসারি ম্যানেজমেন্ট এর যে দোকানদার বা রিডিউসার থাকবে সে একটা ফাংশন। কোন একশনের পারফর্ম করতে বলা হলে কি করবে সে, সেগুলো হ্যান্ডেল করার জন্য সিম্পল সুইচ স্টেটমেন্ট ইউজ করে কাজ করানো হচ্ছে। লক্ষ্য করেন রিডিউসার ফাংশনটা দুইটা প্যারামিটার নেয় প্রথম প্যারামিটারে Current স্টেট , পরের প্যারামিটারে একশন, কোন একশন তাকে করতে বলা হয়েছে সেটা। আমাদের স্টেটে ফ্রুটের Array থাকবে, আর ইনিশিয়াল ভাবে empty array প্রোভাইড করে দিতে পারি, Default Parameter ব্যবহার করে কাজটা সাড়া যাবে। মনে আছে আমরা প্রতিটা একশনকে আইডেন্টিফাই করার জন্য ‘type’ নামের প্রোপার্টি রেখে দিয়েছি? হ্যাঁ, এখন শুধু আমরা সুইচ কেস দিয়ে বলব আমাদের একশনের টাইপ (action.type) যদি ‘SELL_FRUIT’ হয় তাহলে কি করবে, আমাদের রিডিউসার‌ যখন যেটাই return করবে সেটাই হবে‌ আমাদের নতুন state, মানে রিডিউসার যাকিছু return করবে তা নিয়েই state আপডেট হবে। আমাদের যতগুলো একশন আছে কোন একশন এর ফলে স্টেট এর কি হবে সেটা কেস আকারে লিখে রাখবো জাস্ট । এটাই রিডিউসার!

তো একশন হল, রিডিউসার হল। এবার আমাদের স্টোর সেটআপ করা যাক।

এই প্রথম আমরা রিডাক্স থেকে কিছু ইমপোর্ট করে কাজ করতে যাচ্ছি স্টোর ক্রিয়েট করার জন্য রিডাক্স-এ createStore নামে একটি ফাংশন আছে, যেটা ইমপোর্ট করে কল করার সময় first প্যারামিটারে রিডিউসার দিয়ে কল করলেই স্টোর ক্রিয়েট হয়ে যাবে , জাস্ট এটা ভেরিয়েবল-এ এসাইন করে export করে দিলেই বাইরে ইউজ করতে রেডি। (রিডিউসার মাল্টিপল থাকলে combine করে দিতে হবে combineReducer() নামক ফাংশন এর মাধ্যমে)।

শেষ ধাপ, স্টোরটা অ্যাপ্লিকেশনে ব্যাবহারের জন্য অ্যাপ্লিকেশনের মধ্যে প্রোভাইড করে দেওয়া!

রিডাক্স এর প্রোভাইডারটা আমরা react-redux থেকে ইমপোর্ট করে নেব। তারপর আমাদের যেখানে দরকার,আমাদের স্টোর টা দিয়ে প্রবাহিত করে দেব। ইয়েইইই! All steps done!

এখন শুধু ইন্টারেকশন এর পালা। আমাদের যে একশনগুলো আছে, সেগুলো আমরা পারফর্ম করব এবং স্টেট এর ডেটা নিয়ে কাজ করতে পারব। মনে আছে তো? আমরা যে একশন ডিফাইন করে রেখেছি সেগুলো কে পারফর্ম করবে? দোকানদার বা রিডিউসার, আমাদের শুধু রিডিউসার কে বলতে হবে রিডিউসার এই নাও এই একশনটা পারফর্ম করো। আমরা রিডিউসার কে একশনটা করতে বলবো বাকিটা সে-ই করবে, যেভাবে তাকে বলে রেখেছেন, এটাকে বলা হয় একশন ডিসপ্যাচ( Dispatch). ডিসপ্যাচ এর বাংলা অর্থ নিক্ষেপ করা বা ছুঁড়ে মারা। আমরা রিডিউসার এর মুখে একশন ছুঁড়ে মেরে বলবো, নে ভাই, একশন টা পারফর্ম কর। এভাবে আমরা আমাদের একশন ডিসপ্যাচ করে যাব।

শুনতে কঠিন হলেও কঠিন না। আমরা react-redux ইন্সটল করেছিলাম, react-redux আমাদেরকে একটা হুক দিবে এই কাজের জন্য useDispatch।

dispatch(importFruit(listOfFruit)), এইখানের importFruit কি মনে আছে? এটা কিন্তু আমাদের IMPORT_FRUIT একশন এর হেল্পার ফাংশন। এইটাকে কল করলেই IMPORT_FRUIT একশনটা পাওয়া যাবে। এটাকে ডিসপ্যাচ ফাংশন এর আর্গুমেন্ট হিসেবে pass করে কল করে দিলেই কাম তামাম…। আমাদের রিডিউসার এই অ্যাকশন এর এগেনস্টে পারফর্ম করে স্টেট আপডেট করে ফেলবে।

এখন এই স্টেট থেকে ডেটা রিট্রিভ বা বের করে করে কাজ করার পালা।

স্টোর থেকে ডেটা রিট্রিভ করার দুইটা উপায় আছে। একটা হচ্ছে useSelector হুক, আরেকটা connect (higher order function) যেটার মাধ্যমে স্টোর এর সাথে কম্পনেন্ট কানেক্ট করে কম্পনেন্টের props আকারে ডেটা নিয়ে কাজ করা যায়।

আমরা হুক way দেখতেসি, এইটা তুলনামূলক সহজ পদ্ধতি। কিন্তু এটার একটা সমস্যা হচ্ছে, অ্যাসিনক্রোনাস( asynchronous ধরুন, এই allData রিসলভ্ড হবার আগেই আপনি নিচে কোথাও allData নিয়ে কাজ করতে গেলেন ইনিশিয়াল অবস্থায় আনডিফাইন্ড থাকায় ক্র‍্যাশ খেতে পারেন। কিন্তু ব্যাপার না। কন্ডিশনাল দিয়ে সহজভাবে হ্যান্ডেল করে ফেলতে পারবেন, আশা করি। তাই কানেক্ট ওয়ে নিয়ে এ আর্টিকেল আর বড় করতেছি না। আপনি চাইলে জাস্ট একটু ডকুমেন্টেশন পড়ে এটা নিয়েও কাজ করতে পারবেন। https://react-redux.js.org/api/connect

এত বড় আর্টিকেল পড়ার পর একজন বিগিনার এর জন্য মেইন স্টেপ গুলা গুলিয়ে ফেলা স্বাভাবিক। শুধুমাত্র মেইন স্টেপ গুলো নিয়ে স্লাইড গুলো দেখে নিতে পারেন।

https://docs.google.com/presentation/d/1nAbJLaVFQqRvaL0vpU_VbNmX0SlxxHU0DXZwaGlxyr0/edit?usp=sharing

ধন্যবাদ ।

--

--