State Flutter में डेटा प्रबंधन की केंद्रीय वस्तु है, जो StatefulWidget से संबद्ध है और परिवर्तनीय जानकारी संग्रहीत करने और इंटरफ़ेस बनाने के लिए जिम्मेदार है। आधिकारिक Flutter दस्तावेज़ीकरण (Flutter.dev, 2026) के अनुसार, State विजेट के पूरे जीवनचक्र में मौजूद रहता है और इसके पुनर्निर्माण से बच जाता है, UI अपडेट के बीच डेटा स्थिरता सुनिश्चित करता है। स्वयं विजेट के विपरीत, State अपने फ़ील्ड को संशोधित कर सकता है और setState कॉल के माध्यम से पुनर्निर्माण शुरू कर सकता है।
मुख्य बिंदु
State Flutter आर्किटेक्चर में एक ऑब्जेक्ट है जो StatefulWidget के परिवर्तनीय डेटा को संग्रहीत करता है और यह निर्धारित करता है कि यह डेटा इंटरफ़ेस में कैसे प्रदर्शित होता है। प्रत्येक StatefulWidget, ट्री में स्थापित होने पर, createState विधि के माध्यम से एक State ऑब्जेक्ट बनाता है। State विजेट से स्वतंत्र रूप से मौजूद रहता है: यदि पैरेंट नए पैरामीटर के साथ StatefulWidget का पुनर्निर्माण करता है, तो State वही रहता है और widget प्रॉपर्टी के माध्यम से अपडेटेड विजेट प्राप्त करता है।
Flutter आर्किटेक्चरल ओवरव्यू (Google, 2026) के अनुसार, Widget और State का पृथक्करण एक सोच-समझकर लिया गया आर्किटेक्चरल निर्णय है जो फ्रेमवर्क को ट्री तत्वों को पुनः उपयोग करने की अनुमति देता है। विजेट (एक हल्का विवरण) कई बार बनाया और नष्ट किया जा सकता है, लेकिन State (डेटा वाली एक भारी वस्तु) मेमोरी में तब तक रहता है जब तक तत्व ट्री में है। यह पैरेंट विजेट्स के बार-बार पुनर्निर्माण के दौरान डेटा हानि को रोकता है।
State जेनेरिक के माध्यम से StatefulWidget इंटरफ़ेस को लागू करता है: class _MyState extends State<MyWidget>। जेनेरिक State को एक विशिष्ट StatefulWidget प्रकार से बांधता है, जो widget प्रॉपर्टी के माध्यम से इसके फ़ील्ड तक टाइप-सुरक्षित पहुँच प्रदान करता है।
State ऑब्जेक्ट StatefulElement में संग्रहीत होता है — Widget और RenderObject के बीच एक मध्यवर्ती परत। StatefulElement createState के माध्यम से State बनाता है, इसका संदर्भ रखता है, और State को स्वामी के रूप में पास करता है। Element केवल तब नष्ट होता है जब विजेट ट्री से हटा दिया जाता है — तब तक, State मेमोरी में रहता है।
State का जीवनचक्र नियतात्मक है और कॉलों के एक सख्त अनुक्रम से बना है। इस अनुक्रम को समझना सही संसाधन प्रबंधन और मेमोरी लीक को रोकने का आधार है।
initState State बनने पर सबसे पहले कॉल किया जाता है। इस विधि में, कंट्रोलर, स्ट्रीम सब्सक्रिप्शन, टाइमर और फ़ील्ड के प्रारंभिक मान आरंभ किए जाते हैं। पहली पंक्ति में super.initState() कॉल करना अनिवार्य है। initState चरण में, विजेट ट्री अभी पूरी तरह से माउंट नहीं हुआ है, इसलिए MediaQuery.of(context) जैसी विधियाँ सही ढंग से काम नहीं कर सकती हैं।
didChangeDependencies initState के बाद और InheritedWidget निर्भरताओं में प्रत्येक परिवर्तन पर कॉल किया जाता है। यहाँ, initState में नहीं, MediaQuery.of(context) या Theme.of(context) कॉल करना चाहिए, क्योंकि इस समय तक ट्री पहले ही माउंट हो चुका है। यह विधि तब भी कॉल की जाती है यदि विजेट किसी भिन्न संदर्भ में जाता है जहाँ InheritedWidget अन्य मान प्रदान करता है।
build State की मुख्य विधि है जो विजेट ट्री लौटाती है। यह initState के बाद, didChangeDependencies के बाद और प्रत्येक setState के बाद कॉल की जाती है। build विधि का कोई दुष्प्रभाव नहीं होना चाहिए — यह केवल State फ़ील्ड के वर्तमान मानों के आधार पर इंटरफ़ेस का वर्णन करती है।
didUpdateWidget तब कॉल किया जाता है जब पैरेंट नए पैरामीटर के साथ StatefulWidget का पुनर्निर्माण करता है। State पुराने विजेट तक oldWidget के माध्यम से पहुँच प्राप्त करता है और इसकी तुलना नए से कर सकता है। यदि पैरामीटर बदल गए हैं, तो स्थिति को अपडेट किया जा सकता है, नया डेटा लोड किया जा सकता है, या एनीमेशन पुनः शुरू किया जा सकता है।
dispose अंतिम विधि है जहाँ सभी संसाधन मुक्त किए जाते हैं: कंट्रोलर, सब्सक्रिप्शन, टाइमर। dispose के बाद, State को मृत के रूप में चिह्नित किया जाता है: mounted false लौटाता है, setState कॉल करने पर अपवाद उत्पन्न होता है। विधि की अंतिम पंक्ति में super.dispose() कॉल करना अनिवार्य है।
| विधि | कब कॉल की जाती है | अनिवार्य super |
|---|---|---|
| initState | State बनने पर | हाँ, पहली पंक्ति में |
| didChangeDependencies | initState के बाद और InheritedWidget बदलने पर | हाँ |
| build | initState, didChangeDependencies, setState के बाद | नहीं |
| didUpdateWidget | पैरेंट से नया विजेट आने पर | हाँ |
| setState | डेवलपर कॉल पर | नहीं |
| dispose | ट्री से हटाने पर | हाँ, अंतिम पंक्ति में |
State का कार्य तंत्र तीन मुख्य सिद्धांतों पर आधारित है: Element के साथ जुड़ाव, setState के माध्यम से प्रतिक्रियाशीलता, और widget प्रॉपर्टी के माध्यम से पैरेंट तक पहुँच। जब Flutter तत्व ट्री बनाता है और StatefulElement का सामना करता है, तो वह संबद्ध विजेट का createState कॉल करता है। बनाया गया State तत्व में संग्रहीत होता है और तब तक मौजूद रहता है जब तक तत्व हटा नहीं दिया जाता।
जब setState कॉल किया जाता है, State स्वयं को गंदा के रूप में चिह्नित करता है और अगले फ्रेम के लिए पुनर्निर्माण निर्धारित करता है। महत्वपूर्ण: setState तुरंत build कॉल नहीं करता — यह केवल पुनर्निर्माण की आवश्यकता को पंजीकृत करता है। Flutter वर्तमान फ्रेम में सभी गंदे तत्वों को इकट्ठा करता है और उन्हें बैच में पुनर्निर्माण करता है, जो प्रदर्शन को अनुकूलित करता है। build कॉल करने के बाद, State स्वच्छ स्थिति में लौट आता है।
widget प्रॉपर्टी State को StatefulWidget कंस्ट्रक्टर में पास किए गए पैरामीटर पढ़ने की अनुमति देती है। चूँकि StatefulWidget अपरिवर्तनीय है (StatelessWidget की तरह), इसके फ़ील्ड नहीं बदलते — जब पैरामीटर बदलते हैं, तो पैरेंट एक नया विजेट बनाता है, और State इसे didUpdateWidget के माध्यम से प्राप्त करता है। यह सुनिश्चित करता है कि State हमेशा वर्तमान पैरेंट डेटा के साथ काम करता है।
टाइमर द्वारा संशोधित फ़ील्ड के साथ State का मूल उदाहरण। initState, setState और dispose प्रदर्शित करता है:
class _TimerWidgetState extends State<TimerWidget> {
int _seconds = 0;
Timer? _timer;
@override
void initState() {
super.initState();
_timer = Timer.periodic(
const Duration(seconds: 1),
(_) => setState(() => _seconds++),
);
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Text('$_seconds seconds elapsed');
}
}
पैरेंट पैरामीटर तक पहुँचने और didUpdateWidget के माध्यम से उनके परिवर्तनों पर प्रतिक्रिया करने के लिए widget प्रॉपर्टी का उपयोग करने वाला उदाहरण:
class _GreetingState extends State<GreetingWidget> {
String _displayName = '';
@override
void initState() {
super.initState();
_displayName = _formatName(widget.name);
}
@override
void didUpdateWidget(GreetingWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.name != oldWidget.name) {
setState(() {
_displayName = _formatName(widget.name);
});
}
}
String _formatName(String name) => name.trim().isEmpty ? 'Guest' : name;
@override
Widget build(BuildContext context) {
return Text('Hello, $_displayName!');
}
}
दूसरे उदाहरण में, State इनपुट पैरामीटर name में परिवर्तनों को ट्रैक करता है और केवल वास्तविक परिवर्तन होने पर प्रदर्शन को पुनः स्वरूपित करता है। widget.name != oldWidget.name जाँच के बिना, विधि प्रत्येक पैरेंट पुनर्निर्माण पर कॉल की जाती, भले ही नाम न बदला हो — फ्रेमवर्क के लिए अनावश्यक कार्य।
State और StatefulWidget Flutter आर्किटेक्चर में दो अलग-अलग वर्ग हैं जो भिन्न भूमिकाएँ निभाते हैं। StatefulWidget एक हल्का अपरिवर्तनीय आवरण है जो विजेट कॉन्फ़िगरेशन का वर्णन करता है और State बनाता है। State एक भारी वस्तु है जो परिवर्तनीय डेटा संग्रहीत करती है, सब्सक्रिप्शन प्रबंधित करती है और UI बनाती है। यह पृथक्करण Flutter को स्थिति खोए बिना विजेट्स को नष्ट और बनाने की अनुमति देता है।
StatefulWidget के सभी फ़ील्ड final होने चाहिए और कंस्ट्रक्टर में सेट होने चाहिए — वे निर्माण के बाद नहीं बदलते। State, दूसरी ओर, किसी भी समय अपने फ़ील्ड को संशोधित कर सकता है, लेकिन सभी परिवर्तनों से पहले setState कॉल होना चाहिए ताकि Flutter को पुनर्निर्माण की आवश्यकता के बारे में पता चले। यह मुख्य अंतर है: StatefulWidget “क्या दिखाना है” है, State “कैसे दिखाना है और कौन सा डेटा उपयोग करना है” है।
Flutter स्रोत कोड विश्लेषण (Flutter SDK, 2026) के अनुसार, StatefulWidget में केवल एक अनिवार्य फ़ील्ड है — createState, जबकि State के पास BuildContext तक पहुँच है, वह स्ट्रीम की सदस्यता ले सकता है, एनीमेशन और कंट्रोलर प्रबंधित कर सकता है। StatefulWidget को यथासंभव सरल रखने, सभी तर्क को State में स्थानांतरित करने की अनुशंसा की जाती है।
Widget और State का पृथक्करण एक आर्किटेक्चरल निर्णय है जो कॉन्फ़िगरेशन की अपरिवर्तनीयता सुनिश्चित करता है। यदि StatefulWidget स्वयं स्थिति संग्रहीत करता, तो प्रत्येक पैरेंट पुनर्निर्माण पर स्थिति खो जाती। स्थिति को एक अलग ऑब्जेक्ट में ले जाकर, Flutter गारंटी देता है कि डेटा पुनर्निर्माण से बच जाता है, जबकि विजेट हल्के और तुलनीय बने रहते हैं।
State ऑब्जेक्ट पृथक है — इसकी अन्य विजेट्स के State तक सीधी पहुँच नहीं है। विजेट्स के बीच डेटा आदान-प्रदान के लिए InheritedWidget या बाहरी स्थिति प्रबंधन उपकरणों का उपयोग किया जाता है: Provider, Riverpod, Bloc, Redux। प्रत्येक दृष्टिकोण समस्या को अलग तरीके से हल करता है: InheritedWidget विजेट ट्री के माध्यम से काम करता है, Provider DI कंटेनर के माध्यम से, Bloc इवेंट स्ट्रीम के माध्यम से।
उपकरण का चुनाव परियोजना के पैमाने पर निर्भर करता है। छोटे अनुप्रयोग के लिए, InheritedWidget और स्थानीय State पर्याप्त हैं। मध्यम और बड़ी परियोजनाओं के लिए, Riverpod या Bloc की अनुशंसा की जाती है — वे परीक्षण क्षमता, पूर्वानुमान क्षमता और UI से तर्क का पृथक्करण सुनिश्चित करते हैं। State का उपयोग केवल स्थानीय विजेट डेटा (फोकस, स्क्रॉल, एनीमेशन) के लिए किया जाता है।
Flutter सामुदायिक सर्वेक्षण 2025 (Flutter Foundation, दिसंबर 2025) के अनुसार, Riverpod नई परियोजनाओं में सबसे लोकप्रिय स्थिति प्रबंधन समाधान है (38%), उसके बाद Bloc (31%) और Provider (22%) हैं। तीनों उपकरण State के साथ संगत हैं और मानक जीवनचक्र को छोड़ने की आवश्यकता नहीं है।
पहली गलती एक अतुल्यकालिक कॉलबैक में setState से पहले mounted की जाँच करना भूलना है। जब विजेट ट्री से हटा दिया जाता है (उदाहरण के लिए, उपयोगकर्ता स्क्रीन से चला गया), लेकिन एक अतुल्यकालिक संक्रिया (HTTP अनुरोध) अभी भी चल रही है, उसके पूरा होने के बाद State पहले ही मृत होता है। मृत State में setState कॉल करने पर अपवाद उत्पन्न होता है। जाँच if (mounted) setState(...) समस्या हल करती है।
दूसरी गलती didChangeDependencies के बजाय initState में InheritedWidget निर्भरताएँ आरंभ करना है। initState में, संदर्भ अभी माउंट नहीं हुआ है, इसलिए MediaQuery.of(context) अपवाद उत्पन्न करेगा। सभी InheritedWidget निर्भरताएँ didChangeDependencies या build में सेट की जानी चाहिए।
तीसरी गलती setState कॉल किए बिना फ़ील्ड को बदलना है। यदि डेवलपर setState के बिना State फ़ील्ड बदलता है, तो Flutter को परिवर्तन के बारे में पता नहीं चलेगा और UI अपडेट नहीं होगा। उदाहरण के लिए: बाद के setState((){}) के बिना _list.add(item) सूची को बदल देगा, लेकिन स्क्रीन वही रहेगी।
State में अतुल्यकालिक संक्रियाओं के लिए सुरक्षा पैटर्न:
Future<void> _fetchData() async {
final data = await ApiService.fetch();
if (mounted) {
setState(() => _data = data);
}
}
mounted की जाँच सुनिश्चित करती है कि setState केवल जीवित State पर कॉल किया जाए, जिससे “setState called after dispose” अपवाद को रोका जा सके।
अक्सर पूछे जाने वाले प्रश्न
StatefulWidget एक अपरिवर्तनीय विजेट कॉन्फ़िगरेशन है, जबकि State एक परिवर्तनीय वस्तु है जो डेटा संग्रहीत करती है और जीवनचक्र का प्रबंधन करती है। विजेट को पुनः बनाया जा सकता है, State को नहीं। StatefulWidget createState के माध्यम से State बनाता है।
ठीक एक। createState विधि एक बार कॉल की जाती है जब StatefulWidget पहली बार ट्री में स्थापित होता है। भले ही पैरेंट कई बार पुनर्निर्माण करे, State ऑब्जेक्ट वही रहता है जब तक विजेट का प्रकार या Key नहीं बदलता।
mounted एक बूलियन फ़्लैग है जो दिखाता है कि State विजेट ट्री में है या नहीं। dispose कॉल करने के बाद, mounted false हो जाता है। अपवादों से बचने के लिए अतुल्यकालिक कॉलबैक में setState से पहले जाँच के लिए उपयोग किया जाता है।
नहीं। State हमेशा जेनेरिक के माध्यम से एक विशिष्ट StatefulWidget से बंधा होता है: State<T extends StatefulWidget>। विजेट के साथ जुड़ाव के बिना, सीधे State बनाना आर्किटेक्चरल रूप से असंभव है।
एक अपवाद उत्पन्न होता है: “setState called after dispose”। dispose के बाद, State मृत माना जाता है, और setState के माध्यम से UI को पुनर्निर्माण करने का कोई भी प्रयास निषिद्ध है। समाधान प्रत्येक setState से पहले mounted की जाँच करना है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें