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 = ‘नया नाम’ काम करता था (हालाँकि इसकी भी अनुशंसा नहीं की गई थी)। फंक्शनल कंपोनेंट्स में, ऐसा म्यूटेशन बस अनदेखा किया जाता है: 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें