useState হল একটি অন্তর্নির্মিত React হুক যা ফাংশনাল কম্পোনেন্টকে ক্লাস কম্পোনেন্টে রূপান্তর না করেই স্থানীয় স্টেট পরিচালনা করতে দেয়। React 16.8 হুক চালু করেছিল, এবং useState সেগুলির মধ্যে সবচেয়ে বেশি ব্যবহৃত হয়ে ওঠে, ক্লাস-ভিত্তিক পদ্ধতি থেকে this.state এবং this.setState-কে প্রতিস্থাপন করে। React ডকুমেন্টেশন (2025) অনুসারে, আধুনিক React অ্যাপ্লিকেশনে 80% এরও বেশি কম্পোনেন্ট ফর্ম ডেটা, ইন্টারফেস ফ্ল্যাগ এবং কাউন্টার পরিচালনা করতে useState ব্যবহার করে। হুক বর্তমান মান এবং একটি সেটার ফাংশন নিয়ে গঠিত একটি টাপল রিটার্ন করে যা স্টেট আপডেট করে এবং কম্পোনেন্টের পুনঃরেন্ডার ট্রিগার করে।
মূল বিষয়
useState হল একটি মৌলিক React হুক, যা সংস্করণ 16.8-এ যোগ করা হয়েছে, যা ফাংশনাল কম্পোনেন্টকে স্থানীয় স্টেট সংরক্ষণ এবং পরিবর্তন করার ক্ষমতা দেয়। হুক চালু করার আগে, স্টেট শুধুমাত্র ক্লাস কম্পোনেন্টে this.state এবং this.setState-এর মাধ্যমে ব্যবহার করা যেত, যা ফাংশনাল কম্পোনেন্টকে সম্পূর্ণরূপে প্রেজেন্টেশনাল করে তুলেছিল। useState এই সীমাবদ্ধতা দূর করেছে, ফাংশনাল কম্পোনেন্ট ব্যবহার করে সম্পূর্ণ অ্যাপ্লিকেশন লেখার অনুমতি দিয়েছে।
হুক একটি আর্গুমেন্ট নেয় — প্রাথমিক স্টেট মান — এবং দুটি উপাদানের একটি অ্যারে রিটার্ন করে। প্রথম উপাদানটি হল বর্তমান স্টেট মান, এবং দ্বিতীয়টি এটি আপডেট করার জন্য একটি ফাংশন। React গ্যারান্টি দেয় যে সেটার ফাংশন স্থিতিশীল এবং রেন্ডারের মধ্যে পরিবর্তিত হয় না, যা আপনাকে এটি নিরাপদে চাইল্ড কম্পোনেন্টে পাস করতে এবং ক্লোজারে ব্যবহার করতে দেয়।
React DevTools ব্যবহার জরিপ (2024) অনুসারে, useState 96% React অ্যাপ্লিকেশনে ব্যবহৃত হয়, যা এটিকে ইকোসিস্টেমের সবচেয়ে সাধারণ হুক বানিয়েছে। Redux বা Zustand-এর মাধ্যমে গ্লোবাল স্টেট ব্যবহার করা অ্যাপ্লিকেশনেও, useState-এর মাধ্যমে স্থানীয় স্টেট UI স্টেট — খোলা মোডাল, ইনপুট ফিল্ডের মান, সক্রিয় ট্যাব — পরিচালনার প্রাথমিক প্রক্রিয়া হিসাবে রয়ে গেছে।
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
useState-এর অভ্যন্তরীণ প্রক্রিয়া React-এর ফাইবার নোড সিস্টেমের উপর ভিত্তি করে। React-এ প্রতিটি কম্পোনেন্ট একটি ফাইবার নোড দ্বারা উপস্থাপিত হয় যা এর সাথে যুক্ত হুকের একটি লিঙ্কড লিস্ট সংরক্ষণ করে। যখন একটি কম্পোনেন্ট useState কল করে, React এই লিস্টে একটি নতুন নোড তৈরি করে এবং তাতে বর্তমান স্টেট মান এবং আপডেট কিউ-এর একটি রেফারেন্স সংরক্ষণ করে।
যখন সেটার ফাংশন কল করা হয়, React তাৎক্ষণিকভাবে স্টেট আপডেট করে না। পরিবর্তে, এটি আপডেটটিকে একটি মুলতুবি স্টেট কিউ-এ রাখে, কম্পোনেন্টের পুনঃরেন্ডার শিডিউল করে এবং শুধুমাত্র পরবর্তী রেন্ডারের সময় পুরানো এবং প্রয়োগকৃত আপডেটের উপর ভিত্তি করে নতুন স্টেট গণনা করে। এটি ব্যাচিং নিশ্চিত করে — যদি আপনি একটি ইভেন্ট হ্যান্ডলারে সেটার তিনবার কল করেন, React সেগুলিকে একটি একক পুনঃরেন্ডারে গ্রুপ করে।
React টিম — React 18 ওয়ার্কিং গ্রুপ (2024) অনুসারে, React 18-এ স্বয়ংক্রিয় ব্যাচিং প্রসারিত করা হয়েছে: স্টেট আপডেট এখন শুধুমাত্র ইভেন্ট হ্যান্ডলারেই নয়, setTimeout, Promise কলব্যাক এবং নেটিভ ইভেন্ট হ্যান্ডলারেও গ্রুপ হয়। এটি একাধিক স্টেট আপডেটের পরিস্থিতিতে 30% পর্যন্ত কর্মক্ষমতা লাভ দিয়েছে।
যখন নতুন স্টেট পূর্ববর্তীটির উপর নির্ভর করে, তখন সেটার-এর ফাংশনাল ফর্ম ব্যবহার করুন: setCount(prev => prev + 1). React ফাংশনে আপডেটের সময় প্রকৃত স্টেট মান পাস করে, যা ব্যাচ করা আপডেটের সাথেও সঠিকতা নিশ্চিত করে। ফাংশনাল ফর্ম ছাড়া, setCount(count + 1) একাধিকবার পরপর কল করলে পুরানো মান ব্যবহার করতে পারে।
// অলস ইনিশিয়ালাইজেশন — শুধুমাত্র একবার চলে
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// Result: count increased by 3
// NOT batch-safe: stale closure
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
// Result: count increased by 1 (stale closure)
useState-এর মৌলিক সিনট্যাক্স অত্যন্ত সংক্ষিপ্ত: const [state, setState] = useState(initialValue). প্রাথমিক মান শুধুমাত্র প্রথম রেন্ডারের সময় ব্যবহৃত হয়; পরবর্তী রেন্ডারে, React এটি উপেক্ষা করে এবং বর্তমান সংরক্ষিত মান রিটার্ন করে। যদি প্রাথমিক গণনার জন্য ব্যয়বহুল অপারেশনের প্রয়োজন হয়, তবে একটি ইনিশিয়ালাইজার ফাংশন পাস করুন: useState(() => computeExpensiveInitial()).
অলস ইনিশিয়ালাইজেশন বিশেষভাবে গুরুত্বপূর্ণ যখন প্রাথমিক মান localStorage, জটিল ডেটা রূপান্তর বা URL প্যারামিটার পার্সিং থেকে আসে। React ইনিশিয়ালাইজার ফাংশনটি শুধুমাত্র একবার কল করে — যখন কম্পোনেন্ট মাউন্ট হয়, যা পরবর্তী রেন্ডারে সংস্থান সাশ্রয় করে। অলস ইনিশিয়ালাইজেশন ছাড়া, ব্যয়বহুল এক্সপ্রেশনটি প্রতিটি রেন্ডারে মূল্যায়ন করা হবে, এমনকি যদি তার ফলাফল উপেক্ষা করা হয়।
| ফর্ম | উদাহরণ | কখন ব্যবহার করবেন |
|---|---|---|
| সরাসরি | useState(0) | সরল প্রাথমিক মান |
| অলস | useState(() => compute()) | ব্যয়বহুল প্রাথমিক গণনা |
| ফাংশনাল সেটার | setState(prev => prev + 1) | পূর্ববর্তী মানের উপর ভিত্তি করে আপডেট |
| সরাসরি সেটার | setState(newValue) | নতুন মান পুরানোর উপর নির্ভর করে না |
// অবজেক্ট স্টেট — নতুন রেফারেন্স তৈরি করুন
const [user, setUser] = useState(() => {
const saved = localStorage.getItem('user');
return saved ? JSON.parse(saved) : null;
});
useState প্রিমিটিভ (সংখ্যা, স্ট্রিং, বুলিয়ান) এবং রেফারেন্স টাইপ (অ্যারে, অবজেক্ট) উভয়ের সাথে সমানভাবে ভাল কাজ করে। তবে, একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে: প্রিমিটিভের জন্য, React মান দ্বারা পরিবর্তন সনাক্ত করে; অবজেক্ট এবং অ্যারের জন্য, রেফারেন্স দ্বারা। একটি নতুন না তৈরি করে বিদ্যমান অবজেক্ট মিউটেট করলে পুনঃরেন্ডার ট্রিগার হবে না কারণ রেফারেন্স একই থাকে।
অবজেক্ট এবং অ্যারে নিয়ে কাজ করার সময়, সর্বদা পরিবর্তিত ডেটা সহ একটি নতুন কপি তৈরি করুন। অবজেক্টের জন্য, স্প্রেড সিনট্যাক্স ব্যবহার করুন: setUser(prev => ({...prev, name: newName})). অ্যারের জন্য, এমন পদ্ধতি ব্যবহার করুন যা একটি নতুন অ্যারে রিটার্ন করে: filter, map, concat, বা উপাদান যোগ করার জন্য স্প্রেড সিনট্যাক্স। push, pop, splice-এর মতো মিউটেশন পদ্ধতি কাজ করবে না — React সেগুলি উপেক্ষা করবে কারণ অ্যারে রেফারেন্স পরিবর্তিত হয়নি।
// ✅ সঠিক: হুক শীর্ষ স্তরে
const [form, setForm] = useState({ name: '', email: '' });
const updateField = (field, value) =>
setForm(prev => ({ ...prev, [field]: value }));
// ...
const [items, setItems] = useState([]);
const addItem = item =>
setItems(prev => [item, ...prev]);
সব React হুকের মতো, useState দুটি নিয়ম অনুসরণ করে। প্রথম: হুকগুলি শুধুমাত্র আপনার কম্পোনেন্টের শীর্ষ স্তরে কল করুন — সেগুলি শর্ত, লুপ বা নেস্টেড ফাংশনের ভিতরে রাখবেন না। এটি নিশ্চিত করে যে হুকগুলি প্রতিটি রেন্ডারে একই ক্রমে কল করা হয়, যা React-এর অভ্যন্তরীণ লিঙ্কড লিস্টের জন্য গুরুত্বপূর্ণ।
দ্বিতীয় নিয়ম: হুকগুলি শুধুমাত্র React ফাংশনাল কম্পোনেন্ট বা কাস্টম হুক থেকে কল করুন। সাধারণ ফাংশন, কলব্যাক বা ক্লাস কম্পোনেন্ট থেকে useState কল করবেন না। এই নিয়ম লঙ্ঘন করলে Invalid hook call ত্রুটি হয়, যা React রানটাইমে ধরে।
// ❌ পুরানো ক্লোজার সমস্যা
function GoodComponent() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
// ✅ ফাংশনাল আপডেট দিয়ে ঠিক করা হয়েছে
}
// count পুরানো!
function BadComponent() {
if (isLogged) {
const [user, setUser] = useState(null);
}
}
সবচেয়ে সাধারণ ভুল হল নতুন রেফারেন্স তৈরি করার পরিবর্তে অবজেক্ট এবং অ্যারের সরাসরি মিউটেশন। ডেভেলপাররা ক্লাস কম্পোনেন্টের মিউটেবল শৈলীতে অভ্যস্ত, যেখানে this.state.user.name = ‘নতুন নাম’ কাজ করত (যদিও এটি সুপারিশ করা হয়নি)। ফাংশনাল কম্পোনেন্টে, এই ধরনের মিউটেশন simply উপেক্ষা করা হয়: React রেফারেন্স পরিবর্তন দেখতে পায় না এবং কম্পোনেন্ট পুনঃরেন্ডার করে না।
পুরানো ক্লোজার সমস্যা তখন ঘটে যখন useEffect বা ইভেন্ট হ্যান্ডলারে পাস করা একটি কলব্যাক কলব্যাক তৈরি করার সময় ক্লোজার থেকে একটি পুরানো স্টেট মান ক্যাপচার করে। সমাধান হল সেটারের ফাংশনাল ফর্ম ব্যবহার করা বা useEffect ডিপেন্ডেন্সি অ্যারেতে প্রয়োজনীয় মান অন্তর্ভুক্ত করা। React ডকুমেন্টেশন — হুক FAQ (2025) অনুসারে, ভুল ডিপেন্ডেন্সি অ্যারের পরে হুকে বাগের দ্বিতীয় সবচেয়ে সাধারণ কারণ হল পুরানো ক্লোজার।
// ❌ Stale closure problem
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1); // count is stale!
}, 1000);
return () => clearInterval(timer);
}, []);
// ✅ Fixed with functional update
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
প্রায়শই জিজ্ঞাসিত প্রশ্ন
হ্যাঁ, তবে কিছু সতর্কতার সাথে। গভীরভাবে নেস্টেড অবজেক্টের জন্য, প্রতিটি স্তর আপডেটের সময় কপি করার প্রয়োজন: setState(prev => ({...prev, nested: {...prev.nested, key: newValue}})). যদি আপনার তিন বা তার বেশি নেস্টিং স্তর বিশিষ্ট অবজেক্ট থাকে, তাহলে Immer (অপরিবর্তনীয় আপডেটের জন্য একটি লাইব্রেরি) বিবেচনা করুন বা বিভিন্ন স্তরের জন্য স্টেটকে একাধিক useState কলয়ে বিভক্ত করুন।
useState এই অর্থে অ্যাসিঙ্ক্রোনাস যে সেটার কল করলে তাৎক্ষণিকভাবে মান আপডেট হয় না। React আপডেটটিকে একটি কিউ-এ রাখে এবং পরবর্তী রেন্ডারে এটি প্রয়োগ করে। setCount(newValue) এর পরে, বর্তমান ফাংশনে count ভেরিয়েবলটিতে এখনও পুরানো মান থাকে। নতুন মান শুধুমাত্র পরবর্তী কম্পোনেন্ট কলেই উপলব্ধ হবে। ব্যাচিং প্রক্রিয়া নিশ্চিত করে যে একাধিক কল একটি একক রেন্ডারে গ্রুপ হয়।
React একটি Invalid hook call ত্রুটি ছুঁড়বে। হুকগুলি শুধুমাত্র React ফাংশনাল কম্পোনেন্ট বা কাস্টম হুকের (যাদের নাম use দিয়ে শুরু হয়) ভিতরে কল করা যেতে পারে। এই সীমাবদ্ধতা হুক বাস্তবায়নে নির্মিত: তারা স্টেট সংরক্ষণের জন্য কম্পোনেন্টের ফাইবার ট্রি ব্যবহার করে, এবং কম্পোনেন্টের বাইরে, এই ট্রিটি উপলব্ধ নয়।
useState সরল স্বাধীন স্টেট (কাউন্টার, ইনপুট ফিল্ড, ফ্ল্যাগ) এর জন্য উপযুক্ত। useReducer ভাল যখন স্টেট একাধিক ফিল্ড সহ একটি জটিল অবজেক্ট, আপডেট লজিক অ্যাকশন টাইপের উপর নির্ভর করে, বা পরবর্তী স্টেটের জটিল রূপান্তরের প্রয়োজন হয়। একটি ব্যবহারিক নিয়ম: যদি আপনার তিনটির বেশি পরস্পর সম্পর্কিত স্টেট ফিল্ড থাকে, তাহলে useReducer ব্যবহার করুন।
এটি কর্মক্ষমতা কারণে করা হয়। যদি useState স্টেট সিঙ্ক্রোনাসভাবে আপডেট করত, প্রতিটি সেটার কল তাত্ক্ষণিক পুনঃরেন্ডার ট্রিগার করত, যা একটি একক ইভেন্ট হ্যান্ডলারের মধ্যে একাধিক পুনঃঅঙ্কনের দিকে নিয়ে যেত। ব্যাচিং, যেখানে React আপডেটগুলি গ্রুপ করে এবং একটি একক পুনঃরেন্ডার সম্পাদন করে, এটি একটি অপ্টিমাইজেশন যা React 16-এ চালু হয়েছিল এবং React 18-এ স্বয়ংক্রিয় ব্যাচিংয়ের সাথে উল্লেখযোগ্যভাবে উন্নত হয়েছে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন