setState() Flutter میں State کا کلیدی طریقہ ہے، جو فریم ورک کو ڈیٹا کی تبدیلیوں سے آگاہ کرتا ہے اور انٹرفیس کی دوبارہ تعمیر کو متحرک کرتا ہے۔ سرکاری Flutter دستاویزات (Flutter.dev, 2026) کے مطابق، setState StatefulWidget میں ردعمل کا بنیادی طریقہ کار ہے: اسے کال کیے بغیر، UI کو State فیلڈز کی تبدیلیوں کا پتہ نہیں چلے گا اور یہ پچھلی حالت میں رہے گا۔ یہ طریقہ VoidCallback قبول کرتا ہے، جس کے اندر ڈویلپر قابل تبدیل فیلڈز کو تبدیل کرتا ہے، جس کے بعد Flutter خود بخود build کو کال کرتا ہے تاکہ ویجیٹ کو دوبارہ تعمیر کیا جا سکے۔
اہم نکات
setState() Flutter میں State کلاس کا ایک بلٹ ان طریقہ ہے، جو فریم ورک کو مطلع کرنے کے لیے ڈیزائن کیا گیا ہے کہ ویجیٹ کی اندرونی حالت تبدیل ہو گئی ہے اور UI کو دوبارہ تعمیر کرنے کی ضرورت ہے۔ setState کو کال کیے بغیر، Flutter تبدیلیوں کے بارے میں نہیں جانتا — چاہے State فیلڈز میں ترمیم کی گئی ہو، والدین کی طرف سے اگلی جبری دوبارہ تعمیر تک انٹرفیس تبدیل نہیں ہوگا۔
طریقہ کا دستخط: void setState(VoidCallback fn)۔ کال بیک setState کے اندر ہم آہنگی سے انجام پاتا ہے، اور اس کے مکمل ہونے کے بعد ہی State کو گندا نشان زد کیا جاتا ہے۔ یہ ضمانت دیتا ہے کہ دوبارہ تعمیر سے پہلے تمام تبدیلیاں ایٹمی طور پر لاگو ہوتی ہیں۔ Dart زبان کی خصوصیات (Dart Team, 2026) کے مطابق، setState کی ایٹمیت دوڑ کے حالات کو روکتی ہے جہاں build جزوی طور پر اپ ڈیٹ شدہ حالت دیکھ سکتا ہے۔
setState کوئی دلیل نہیں لیتا، کوئی قدر واپس نہیں کرتا، اور اوور رائیڈ نہیں کیا جا سکتا۔ یہ State کلاس کا ایک حتمی (مہر بند) طریقہ ہے۔ ڈویلپر اس کے رویے کو تبدیل نہیں کر سکتا — صرف اسے مطلوبہ طور پر استعمال کر سکتا ہے۔ State سے باہر (مثال کے طور پر، کسی دوسری کلاس سے) setState کال کرنے کی کوشش ناممکن ہے کیونکہ طریقہ State کلاس میں اعلان کردہ ہے۔
یہ سوچنا کہ setState خود حالت بدلتا ہے ایک عام غلط فہمی ہے۔ یہ سچ نہیں ہے۔ setState صرف دیے گئے کال بیک کو کال کرتا ہے (جس میں ڈویلپر فیلڈز کو تبدیل کرتا ہے) اور پھر فریم ورک کو build کی ضرورت کا اشارہ دیتا ہے۔ کال بیک لازمی ہے — null یا خالی کال بیک دینے سے خرابی پیدا ہوگی۔
setState() کے کام کرنے کے طریقہ کار کو چار مراحل میں تقسیم کیا جا سکتا ہے۔ پہلا — کال بیک کے ساتھ طریقہ کو کال کرنا۔ دوسرا — کال بیک کا ہم آہنگ نفاذ، جس کے اندر State فیلڈز میں ترمیم کی جاتی ہے۔ تیسرا — State کو ایک خاص فیلڈ _dirty میں گندا نشان زد کیا جاتا ہے۔ چوتھا — موجودہ مائیکرو ٹاسک کے اختتام پر، Flutter تمام گندے عناصر کو دہراتا ہے اور درخت میں ظاہر ہونے کی ترتیب سے ان کا build کال کرتا ہے۔
ایک اہم تفصیل: setState فوری طور پر build کو کال نہیں کرتا۔ Flutter بیچ اپ ڈیٹ کی حکمت عملی استعمال کرتا ہے: تمام گندے عناصر جمع کیے جاتے ہیں اور ایک ہی فریم میں دوبارہ تعمیر کیے جاتے ہیں۔ اس کا مطلب ہے کہ اگر setState کو ایک ہم آہنگ بلاک کے اندر کئی بار کال کیا جائے، تو build صرف ایک بار انجام پائے گا — تمام تبدیلیاں مکمل ہونے کے بعد۔ یہ اصلاح فی فریم کئی بار دوبارہ تعمیر کو روکتی ہے۔
Flutter Engine Team (Google, 2025) کے مطابق، گندا پرچم کا طریقہ کار BuildOwner._dirtyElements پاس پر مبنی ہے۔ ہر گندا StatefulElement فہرست میں شامل کیا جاتا ہے اور فریم اپ ڈیٹ مرحلے میں پروسیس کیا جاتا ہے۔ اگر پروسیسنگ سے پہلے کوئی ویجیٹ درخت سے ہٹا دیا گیا تھا، تو یہ خود بخود گندے عناصر کی فہرست سے خارج کر دیا جاتا ہے۔
کاؤنٹر بڑھانے کے ساتھ setState() کی بنیادی مثال۔ صحیح استعمال کو ظاہر کرتا ہے: کال بیک کے اندر فیلڈ میں ترمیم:
class _CounterState extends State<CounterWidget> {
int _count = 0;
void _increment() {
setState(() {
_count++; // کال بیک کے اندر فیلڈ تبدیل کرنا
});
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _increment,
child: Text('$_count'),
);
}
}
ٹیکسٹ فیلڈ اور کنٹرولر کے ساتھ مثال — پاس ورڈ مرئیت کے انتظام کے لیے setState():
class _PasswordFieldState extends State<PasswordField> {
bool _obscured = true;
final _controller = TextEditingController();
void _toggleVisibility() {
setState(() {
_obscured = !_obscured;
});
}
@override
Widget build(BuildContext context) {
return TextField(
controller: _controller,
obscureText: _obscured,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(_obscured ? Icons.visibility : Icons.visibility_off),
onPressed: _toggleVisibility,
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
اس مثال میں، setState() صرف بولین فیلڈ _obscured کو تبدیل کرتا ہے، جو نئے آئیکن اور ڈسپلے موڈ کے ساتھ TextField کی دوبارہ تعمیر کو متحرک کرتا ہے۔ ٹیکسٹ کنٹرولر دوبارہ نہیں بنایا جاتا — یہ initState میں ایک بار شروع کیا جاتا ہے اور dispose میں جاری کیا جاتا ہے۔
اگر آپ کو متعدد فیلڈز تبدیل کرنے کی ضرورت ہے، تو تمام تبدیلیاں ایک setState کے اندر کی جانی چاہئیں۔ یہ ضمانت دیتا ہے کہ build ایک مستقل حالت دیکھے گا:
setState(() {
_isLoading = false;
_items = newItems;
_error = null;
});
ایک کال بیک میں تین فیلڈز تبدیل ہوتے ہیں — build ایک بار انجام پائے گا اور تمام تبدیلیوں کو بیک وقت دیکھے گا۔ اگر ہر کال ایک علیحدہ setState ہوتی، تو بھی build گندے عناصر کی بیچ پروسیسنگ کی بدولت صرف ایک بار انجام پاتا۔
setState() کی ایک اہم ترین باریکی اس کا غیر ہم آہنگ کارروائیوں کے ساتھ رویہ ہے۔ setState کال بیک ہم آہنگی سے انجام پاتا ہے، لیکن اگر اس کے اندر await کال کیا جائے، تو await کے بعد کا کوڈ setState کے اپنا کام مکمل کرنے کے بعد انجام پائے گا۔ اس کا مطلب ہے کہ await کے بعد فیلڈ کی تبدیلیاں موجودہ setState کے ذریعے قبض نہیں کی جائیں گی۔
صحیح طریقہ: غیر ہم آہنگ کارروائی setState کے باہر کی جاتی ہے، اور setState اس کے مکمل ہونے کے بعد کال کیا جاتا ہے۔ نتیجہ حاصل کرنے اور setState کال کرنے کے درمیان کا تمام کوڈ await کے بعد ہم آہنگ سیاق و سباق میں چلتا ہے:
// درست: await setState سے باہر
Future<void> _loadData() async {
final result = await ApiService.fetchData();
setState(() {
_data = result;
_isLoading = false;
});
}
// غلط: await setState کے اندر — اپ ڈیٹ کی ضمانت نہیں
void _loadDataWrong() {
setState(() async {
_data = await ApiService.fetchData(); // setState await مکمل ہونے سے پہلے واپس آتا ہے
_isLoading = false; // یہ کوڈ setState کے ذریعے قبض نہیں کیا گیا
});
}
Flutter دستاویزات (Dart async patterns, 2026) کے مطابق، setState کو غیر ہم آہنگ کال بیک دینا ایک مخالف نمونہ ہے کیونکہ setState ایک VoidCallback (ہم آہنگ فنکشن) کی توقع کرتا ہے، جبکہ غیر ہم آہنگ فنکشن ایک Future واپس کرتا ہے جسے نظر انداز کر دیا جاتا ہے۔ ایسے کال بیک میں پہلے await کے بعد کی تبدیلیاں فریم ورک کے ذریعے صحیح طریقے سے پروسیس نہیں ہوں گی۔
غیر ہم آہنگ کارروائی کے بعد setState() کال کرنے سے پہلے، ہمیشہ mounted چیک کریں:
if (mounted) {
setState(() => _data = data);
}
اگر غیر ہم آہنگ کارروائی کے دوران ویجیٹ کو درخت سے ہٹا دیا گیا تھا، تو mounted false ہو جائے گا اور setState کال نہیں ہوگا۔ یہ استثناء اور وسائل کے رساؤ کو روکتا ہے۔
setState() ایک آسان لیکن ممکنہ طور پر مہنگا طریقہ کار ہے اگر بے سوچے سمجھے استعمال کیا جائے۔ ہر setState کال پورے ویجیٹ اور اس کی تمام اولاد (اگر وہ const نہیں ہیں) کو دوبارہ تعمیر کرتی ہے۔ گہرے درختوں میں یا بار بار کالوں کے ساتھ، یہ FPS میں کمی کا باعث بن سکتا ہے۔
بنیادی اصلاح کی حکمت عملیاں: دوبارہ تعمیر کے علاقے کو کم سے کم کریں (تبدیل ہونے والے UI حصوں کو علیحدہ StatefulWidgets میں نکالیں)، ناقابل تبدیل بچوں کے لیے const استعمال کریں، اور والدین ویجیٹ میں setState کال کرنے سے گریز کریں اگر صرف ایک چھوٹی UX تفصیل تبدیل ہوئی ہے۔ اگر حالت زیادہ تعدد پر اپ ڈیٹ ہوتی ہے (اینیمیشن، ڈیٹا اسٹریم)، تو AnimatedBuilder یا ValueListenableBuilder پر غور کریں۔
Flutter کارکردگی کے بہترین طریقوں (Flutter.dev، فروری 2026) کے مطابق، حقیقی ایپلی کیشنز کی پروفائلنگ سے پتہ چلتا ہے کہ تمام setState کالوں کا 40% تک const چائلڈ ویجیٹس یا ری ایکٹو بلڈرز (StreamBuilder, FutureBuilder) سے تبدیل کیا جا سکتا ہے۔ اس سے اوسط فریم تعمیر کا وقت 15–25% کم ہو جاتا ہے۔
| منظر | متبادل | فائدہ |
|---|---|---|
| اینیمیشن | AnimatedBuilder | صرف اینی میٹڈ ویجیٹ کو دوبارہ تعمیر کرتا ہے |
| ڈیٹا اسٹریم | StreamBuilder | ہر اسٹریم عنصر پر ردعمل ظاہر کرتا ہے |
| مستقبل کا نتیجہ | FutureBuilder | لوڈنگ/خرابی کی حالتوں کا انتظام کرتا ہے |
| مقامی قدر | ValueListenableBuilder | ایک قدر کی تبدیلیوں پر ردعمل ظاہر کرتا ہے |
setState() کی استعداد کے باوجود، بڑے منصوبوں میں یہ بنیادی طور پر مقامی حالت کے لیے استعمال ہوتا ہے۔ عالمی یا مشترکہ حالت کے لیے، خصوصی حل استعمال کیے جاتے ہیں، جن میں سے ہر ایک setState کو تبدیل یا لپیٹتا ہے۔
Provider setState کے مشابہ کے طور پر ChangeNotifier + notifyListeners استعمال کرتا ہے، لیکن متعدد ویجیٹس کو سبسکرائب کرنے کی صلاحیت کے ساتھ۔ Bloc Streams استعمال کرتا ہے — StreamController میں واقعات شامل کرکے حالت تبدیل کی جاتی ہے۔ Riverpod طریقوں کو یکجا کرتا ہے، StatefulWidget سے بندھن کے بغیر مقامی (StateProvider) اور غیر ہم آہنگ (AsyncNotifier) دونوں انتظام فراہم کرتا ہے۔ تینوں طریقے دستی طور پر setState کال کرنے کی ضرورت کو ختم کرتے ہیں — ڈیٹا تبدیل ہونے پر UI اپ ڈیٹ خود بخود ہوتی ہے۔
Flutter کمیونٹی سروے 2025 (Flutter Foundation، دسمبر 2025) کے مطابق، 74% ڈویلپرز setState کے علاوہ کم از کم ایک اسٹیٹ مینجمنٹ ٹول استعمال کرتے ہیں۔ اسی وقت، 92% ٹیکسٹ فیلڈز، چیک باکسز یا سادہ کاؤنٹرز کے مقامی ڈیٹا کے لیے setState استعمال کرتے رہتے ہیں — اسے بہترین عمل سمجھا جاتا ہے۔
پہلی اور سب سے خطرناک غلطی dispose کے بعد setState کال کرنا ہے۔ initState میں شروع کی گئی غیر ہم آہنگ کارروائی، صارف اسکرین سے چلا گیا، ویجیٹ ہٹا دیا گیا، اور غیر ہم آہنگ کال بیک setState کال کرتا ہے — ایپ استثناء کے ساتھ کریش ہو جاتی ہے۔ حل — کال کرنے سے پہلے ہمیشہ mounted چیک کریں۔
دوسری غلطی build کے اندر setState کال کرنا ہے۔ یہ ایک لامحدود لوپ کی طرف لے جاتا ہے: build → setState → گندا → build → setState → ... Flutter ایسی کال کو بلاک نہیں کرتا (آپ کو StackOverflowError ملے گا)۔ setState صرف کسی واقعہ کے جواب میں کال کیا جا سکتا ہے (بٹن دبانا، Future مکمل ہونا، اسٹریم سے ڈیٹا)۔
تیسری غلطی setState کال کیے بغیر State فیلڈز میں ترمیم کرنا ہے۔ ڈویلپر _count++ لکھتا ہے اور UI اپ ڈیٹ ہونے کی توقع کرتا ہے۔ Flutter خود بخود فیلڈ تبدیلیوں کو ٹریک نہیں کر سکتا — اسے setState کے ذریعے واضح سگنل کی ضرورت ہے۔ یہ Vue.js جیسے ری ایکٹو فریم ورکس سے بنیادی فرق ہے، جہاں ڈیٹا کی تبدیلیاں خود بخود اپ ڈیٹس کو متحرک کرتی ہیں۔
چوتھی غلطی setState کو غیر ہم آہنگ کال بیک (async lambda) کے ساتھ کال کرنا ہے۔ جیسا کہ غیر ہم آہنگی سیکشن میں بیان کیا گیا ہے، await کے بعد کی تبدیلیاں قبض نہیں کی جائیں گی، جس کی وجہ سے ایسی خرابیاں پیدا ہوتی ہیں جنہیں دوبارہ پیدا کرنا مشکل ہے۔ ایک ہم آہنگ کال بیک استعمال کریں اور await کے بعد setState کال کریں۔
mounted چیک کریںاکثر پوچھے گئے سوالات
setState() Flutter کو مطلع کرتا ہے کہ StatefulWidget کا اندرونی ڈیٹا تبدیل ہو گیا ہے اور UI کو دوبارہ تعمیر کرنے کی ضرورت ہے۔ یہ طریقہ ایک کال بیک قبول کرتا ہے، اسے ہم آہنگی سے انجام دیتا ہے، ویجیٹ کو گندا نشان زد کرتا ہے، اور اگلے فریم میں build کال کرنے کا شیڈول بناتا ہے۔
UI اپ ڈیٹ نہیں ہوگا۔ Flutter خود بخود فیلڈ تبدیلیوں کو ٹریک نہیں کرتا۔ فیلڈ کی قدر میموری میں بدل جاتی ہے، لیکن ویجیٹ والدین کی طرف سے اگلی جبری دوبارہ تعمیر تک پچھلی حالت میں رہتا ہے۔
نہیں۔ یہ ایک لامحدود لوپ کی طرف لے جاتا ہے: build setState کال کرتا ہے، جو ویجیٹ کو گندا نشان زد کرتا ہے اور دوبارہ build کال کرتا ہے۔ Flutter اس صورتحال کو بلاک نہیں کرتا — ایپ StackOverflowError سے کریش ہو جائے گی۔
Build ایک بار انجام پائے گا۔ Flutter تمام گندے عناصر کو جمع کرتا ہے اور فریم کے آخر میں انہیں بیچ میں دوبارہ تعمیر کرتا ہے۔ پروسیسنگ سے پہلے دوسرا setState بس عنصر کو اسی گندے عناصر کی فہرست میں شامل کرتا ہے — کوئی بار بار دوبارہ تعمیر نہیں ہوتی۔
mounted ایک بولین پرچم ہے جو ظاہر کرتا ہے کہ ویجیٹ ابھی بھی درخت میں ہے۔ اگر mounted چیک کیے بغیر غیر ہم آہنگ کارروائی کے بعد setState کال کیا جائے اور ویجیٹ پہلے ہی ہٹا دیا گیا ہو — ایپ “setState called after dispose” استثناء کے ساتھ کریش ہو جاتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں