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 के पूरा होने से पहले लौटता है
_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 Performance Best Practices (Flutter.dev, फरवरी 2026) के अनुसार, वास्तविक अनुप्रयोगों की प्रोफाइलिंग से पता चलता है कि 40% तक setState कॉल को 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 Community Survey 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 जैसे प्रतिक्रियाशील फ्रेमवर्क से एक मौलिक अंतर है, जहाँ डेटा परिवर्तन स्वचालित रूप से अपडेट ट्रिगर करते हैं।
चौथी गलती अतुल्यकालिक कॉलबैक (async lambda) के साथ setState कॉल करना है। जैसा कि अतुल्यकालिकता अनुभाग में वर्णित है, await के बाद परिवर्तन कैप्चर नहीं किए जाएंगे, जिससे बग उत्पन्न होते हैं जिन्हें पुनः उत्पन्न करना कठिन है। एक तुल्यकालिक कॉलबैक का उपयोग करें और await के बाद setState कॉल करें।
mounted जाँचेंअक्सर पूछे जाने वाले प्रश्न
setState() Flutter को सूचित करता है कि StatefulWidget का आंतरिक डेटा बदल गया है और UI को पुनर्निर्मित करने की आवश्यकता है। यह विधि एक कॉलबैक स्वीकार करती है, इसे तुल्यकालिक रूप से निष्पादित करती है, विजेट को गंदा चिह्नित करती है, और अगले फ्रेम में build कॉल करने की योजना बनाती है।
UI अपडेट नहीं होगा। Flutter स्वचालित रूप से फ़ील्ड परिवर्तनों को ट्रैक नहीं करता। फ़ील्ड का मान मेमोरी में बदल जाता है, लेकिन विजेट पैरेंट द्वारा अगले अनिवार्य पुनर्निर्माण तक अपनी पिछली स्थिति में बना रहता है।
नहीं। यह एक अनंत लूप की ओर ले जाता है: build setState कॉल करता है, जो विजेट को गंदा चिह्नित करता है और फिर से build कॉल करता है। Flutter इस स्थिति को ब्लॉक नहीं करता — ऐप StackOverflowError से क्रैश हो जाएगा।
Build एक बार निष्पादित होगा। Flutter सभी गंदे तत्वों को इकट्ठा करता है और फ्रेम के अंत में उन्हें बैच में पुनर्निर्मित करता है। प्रसंस्करण से पहले दूसरा setState बस उसी गंदे तत्व सूची में तत्व जोड़ता है — कोई दोहरा पुनर्निर्माण नहीं होता।
mounted एक बूलियन फ्लैग है जो दर्शाता है कि विजेट अभी भी पेड़ में है। यदि setState को mounted जाँचे बिना अतुल्यकालिक संचालन के बाद कॉल किया जाता है और विजेट पहले ही हटा दिया गया है — ऐप अपवाद "setState called after dispose" के साथ क्रैश हो जाता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें