Reactive Accelerator
React Js
React State Management Deep Dive
3.3 - Choosing the state Structure in React

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

  1. Group Related State
  2. Avoid Contradictions in State
  3. Avoid Redundant State
  4. Avoid Duplication is State
  5. Avoid Deeply Nested State

Group Related State (একইজাতীয় বা পারস্পারিক সম্পর্কযুক্ত স্টেটগুলোকে একটা স্টেটে গ্রুপ করে নেয়া)

যদি এমন হয় যে মাল্টিপল স্টেট কিন্তু একটা আরেকটার সাথে সম্পর্কযুক্ত,এবং একটা চেঞ্জ করলে অন্যটাও চেঞ্জ করার প্রয়োজন পরে সেই ক্ষেত্রে স্টেটগুলোকে একটা স্টেট হিসেবে গ্রুপ করে নেয়া উচিত। যেমন ঃ

const [x, setX] = useState(0);
const [y, setY] = useState(0);

এখানে একটা কাস্টম কার্সর বানানোর জন্য x এবং y নামে দুইটা স্টেট নেয়া হয়েছে, এবং মাউসমুভ করার সাথে সাথে স্টেটগুলো আপডেট হতে হবে, তার মানে মাউসমুভ হলেই আমাকে x এবং y দুইটা স্টেট পরিবর্তন করতে হবে। তাহলে আমরা এভাবে দুইটা স্টেট না নিয়ে বরং একটা স্টেট নিতে পারি positionনামে এবং এর ভ্যালু হিসেবে x এবং y কে একটা অবজেক্ট আকারে রাখতে পারি।

const [position, setPosition] = useState({ x: 0, y: 0 });

Avoid contradictions in state (একই সাথে দুইটাই কখনও সত্য অথবা মিথ্যা না হলে দুইটা কে একটা স্টেট হিসেবে নেয়া)

এমন অনেক সিনারিও আসতে পারে যেখানে হয়তো দুইটা স্টেট আছে যেখানে হয়তো দুইটা স্টেট আছে,কিন্তু স্টেট দুইটা কখনোই একইসাথে সত্য অথবা একই সাথে মিথ্যা হতে পারেনা। এসব স্টেটকে বলা হয় Contradiction in State। এমন হলে দুইটা স্টেট কখনোই নেয়া উচিত না,বরং একটা স্টেট দিয়েই দুইটাকেই ম্যনেজ করা উচিত।

উদাহরণসরূপ একটা লাইটের কথা চিন্তা করুনঃ

একটা লাইট আছে, যার দুইটা স্টেট

১। লাইট জালানো অবস্থা (isOn)

২। লাইট বন্ধ অবস্থা (isOff)

const [isOn, setIsOn] = useState(true);
const [isOff, setIsOff] = useState(true);

এখানে এই দুইটা স্টেট কি কখনো একইসাথে দুইটাই true অথবা false হতে পারে? মানে একই সাথে লাইট জালানো বা বন্ধ করা থাকতে পারে ? না সেটা কখনই হতে পারেনা, এটাকেই বলা হয় Contradiction in State। এমন অবস্থায় আমাদের একটাই স্টেট নেয়া উচিত যেমনঃ

const [lightStatus, setLigthStatus] = useState("on");

এভাবে আমরা একটা স্টেট দিয়েই লাইটের দুইটা অবস্থা ম্যানেজ করতে পারি।

Avoid redundant state (অপ্রয়োজনীয় স্টেট না নেয়া বা পরিহার করা)

যদি আমরা কোন স্টেটকে অন্য স্টেট থেকে কেলকুলেট করে নিয়ে ব্যাভারা করতে পারি তাহলে আমাদের নতুন স্টেট না নিয়ে সেই কেলকুলেটেড স্টেট দিয়েই কাজ করা উচিত।

এটাকে Derived Stateও বলা হয়ে থাকে

  • Derived State: যখন কোন ভ্যালু অন্য কোন স্টেট এর ভ্যালু থেকে calculate করে ব্যাবহার করা যায়, তখন সেই Calculated ভ্যারিয়েবল কে Derived State বলা হয়

ধরুন আমাদের এমন তিনটা স্টেট ম্যানেজ করা লাগবে,firstName, lastName, fullName। এখেত্রে আমদের স্টেট গুলো হবে এমন,

const [firstName, setFirstName] = useState("Shahadat");
const [lastName, setLastName] = useState("Hussain");
const [fullName, setFullName] = useState("Shahadat Hussain");

চিন্তা করে দেখেনতো, এখানে কি আমাদের fullName স্টেট-এর কোন দরকার ছিল? আমরা চাইলেইতো firstName,এবং lastName থেকে fullName টা বানিয়ে নিতে পারতাম এভাবে,

const fullName = firstName + " " + lastName;

এক্ষেত্রে

const [fullName, setFullName] = useState("Shahadat Hussain");

এই স্টেট টা ছিল Redundant বা অপ্রয়োজনীয়। আমাদের এসব Redundant স্টেটকে Avoid করতে হবে।

Don't mirror props in state (প্রপ্স মিরর করা এড়িয়ে চলতে হবে)

একটা স্টেটকে যখন প্যারেন্ট কম্পোনেন্ট এ ডিক্লেয়ার করে সেটার ভ্যালুটা চাইল্ড কম্পোনেন্টে পাস করা হয়, এবং চাইল্ড কম্পোনেন্ট সেই প্রপ্সটা নিয়ে আবার তার নিজস্ব স্টেট এর ভ্যালুকে ইনিশিয়ালাইজ করে,সেটা কে বলা হয় প্রপ্স মিরর করা।

এটা করা যাবেনা, কেননা যদি আপনি একবার কোন স্টেট ভ্যালু প্যারেন্ট থেকে চাইল্ডে পাস করেছেন এবং সেটা চাইল্ডের নিজস্ব স্টেট ভ্যরিয়েবল এর ইনিশিয়াল ভ্যালু হিসেবে ব্যাবহার করেছেন,

তখন যদি আপনি চাইল্ড কম্পোনেন্ট থেকে স্টেট ভ্যালু চেঞ্জ করেত চান,তখন চাইল্ড থেকে সেটা পরিবর্তন করতে পারলেও, যদি প্যারেন্ট থেকে সেট স্টেট যেটা আপনি প্রপ্স হিসেবে চাইল্ডে পাঠিয়েছেন,সেটার কোন কন্ট্রোল থাকবেনা,এবং প্যারেন্ট থেকে তা পরিবর্তন করা যাবেনা। কেননা স্টেট এর ইনিশিয়াল ভ্যালু কম্পোনেন্টের প্রথম রেন্ডারেই ইনিশিয়ালাইজ হয়, পরে আর ইনিশিয়াল ভ্যালু চেঞ্জ হয়না। শুধু setter function এর মাধ্যমেই সেই স্টেট এর ভ্যালু চেঞ্জ করা যায়।

তাই এখেত্রে প্যারেন্ট কম্পোনেন্টে সেই স্টেটটা পরিবর্তন করলেও তা কিন্তু প্রপ্স হয়ে আর চাইল্ড কম্পোনেন্টে যাবেনা, কেননা প্রথম রেন্ডারেই চাইল্ডের স্টেটের ইনিশিয়াল ভ্যালু সেট হয়ে গেছে।

Avoid duplication in state (ডুপ্লিকেট স্টেট নেয়া যাবেনা)

একি ভ্যালু যদি মাল্টিপল স্টেট ভ্যারিয়েবল ব্যাবহার করে সেটাকে ডুপ্লিকেট করা বলে। আমাদের এসব ডুপ্লিকেট স্টেট এর ব্যাপারে সতর্ক থাকতে হবে।

অর্থাৎ যদি এমন হয় যে আমাদের কোন স্টেট ভ্যারিয়েবল এ কিছু ভ্যালু আছে,এবং সেই একই ভ্যালু দিয়ে আমরা আরও একটা স্টেট নিয়েছি, সেটাকে ডুপ্লিকেট করা বলা হয়, স্টেট ডুপ্লিকেট করা যাবেনা,প্রয়োজনে এক্ষেত্রে Derived State ব্যাবহার করতে হবে।

Avoid deeply nested state (ডিপলি নেস্টেড অবজেক্ট কে স্টেট হিসেবে নেয়া থেকে বিরত থাকতে হবে)

যদি এমন হয় যে আমাদের এমন একটা স্টেট আছে যা একটা অবজেক্ট এবং তার প্রপারর্টি হিসেবে আরও একটা অবজেক্ট আছে, এবং সেই নেস্টেড অবজেক্ট এর-ও আরও নেস্টেড অনেক অবঞ্জেক্ট আছে, এভাবে অনেক লেয়ার ডীপ একটা নেশটেড অবজেক্ট । যা একটা কমপ্লেক্স স্ট্রাকচার।

এমন স্ট্রাকচার নিয়ে কাজ করলে স্টেট আপডেট করতে হলে সেটা কোডের কপ্লেক্সিটি বাড়াবে,বাগ হতে পারে, কোডটার রিডেবিলিটি নষ্ট হবে। তাই এমন অবজেক্টকে স্টেট হিসেবে নেয়া পরিহার করতে হবে।

সেক্ষেত্রে সেই অবজেক্ট ডাটাকে normalize বা flatten করে নিয়ে তারপর স্টেট হিসেবে ব্যাবহার করতে হবে।