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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں