State — Flutter-da ma'lumotlarni boshqarishning markaziy obyekti bo'lib, StatefulWidget bilan bog'langan va o'zgaruvchan ma'lumotlarni saqlash hamda interfeysni qurish uchun javobgardir. Flutter rasmiy hujjatlariga ko'ra (Flutter.dev, 2026), State vidjetning butun hayot aylanishi davomida mavjud bo'lib, uning qayta qurilishlaridan omon qoladi va UI yangilanishlari o'rtasida ma'lumotlar izchilligini ta'minlaydi. Vidjetning o'zidan farqli o'laroq, State o'z maydonlarini o'zgartirishi va setState chaqiruvi orqali qayta qurishni boshlashi mumkin.
Asosiy
State — Flutter arxitekturasida StatefulWidget-ning o'zgaruvchan ma'lumotlarini saqlaydigan va bu ma'lumotlarning interfeysda qanday ko'rsatilishini belgilaydigan obyektdir. Har bir StatefulWidget daraxtga joylashtirilganda createState metodi orqali aynan bitta State obyektini yaratadi. State vidjetdan mustaqil ravishda mavjud: agar ota-ona StatefulWidget-ni yangi parametrlar bilan qayta qursa, State avvalgidek qoladi va yangilangan vidjetni widget xususiyati orqali oladi.
Flutter Architectural Overview-ga (Google, 2026) ko'ra, Widget va State-ni ajratish framework-ga daraxt elementlarini qayta ishlatish imkonini beradigan ongli arxitektura qaroridir. Vidjet (engil tavsif) bir necha marta yaratilishi va yo'q qilinishi mumkin, ammo State (ma'lumotlarga ega og'ir obyekt) element daraxtda ekan, xotirada qoladi. Bu ota-ona vidjetlarning tez-tez qayta qurilishida ma'lumot yo'qotilishining oldini oladi.
State StatefulWidget interfeysini generik orqali amalga oshiradi: class _MyState extends State<MyWidget>. Generik State-ni muayyan StatefulWidget turi bilan bog'laydi va widget xususiyati orqali uning maydonlariga tur-xavfsiz kirishni ta'minlaydi.
State obyekti StatefulElement ichida saqlanadi — Widget va RenderObject o'rtasidagi oraliq qatlam. StatefulElement createState orqali State yaratadi, unga havolani saqlaydi va State-ni egasi sifatida uzatadi. Element faqat vidjet daraxtdan o'chirilganda yo'q qilinadi — shu paytgacha State xotirada yashaydi.
Hayot aylanishi deterministik bo'lib, qat'iy chaqiruvlar ketma-ketligidan iborat. Ushbu ketma-ketlikni tushunish resurslar bilan to'g'ri ishlash va xotira oqishining oldini olish uchun asosdir.
initState State yaratilganda birinchi bo'lib chaqiriladi. Bu metodda kontrollerlar, ma'lumot oqimlariga obunalar, taymerlar va maydonlarning boshlang'ich qiymatlari sozlanadi. Birinchi qatorda super.initState() chaqiruvi majburiydir. initState bosqichida vidjetlar daraxti hali to'liq o'rnatilmagan, shuning uchun MediaQuery.of(context) kabi metodlar noto'g'ri ishlashi mumkin.
didChangeDependencies initState-dan keyin va InheritedWidget bog'liqliklari har o'zgarganda chaqiriladi. Aynan shu yerda, initState-da emas, MediaQuery.of(context) yoki Theme.of(context) chaqirilishi kerak, chunki bu vaqtda daraxt allaqachon o'rnatilgan. Bu metod shuningdek, vidjet InheritedWidget boshqa qiymatlarni taqdim etadigan boshqa kontekstga ko'chirilganda ham chaqiriladi.
build — State-ning asosiy metodi bo'lib, vidjetlar daraxtini qaytaradi. initState-dan keyin, didChangeDependencies-dan keyin va har bir setState-dan keyin chaqiriladi. build metodi yon ta'sirlarga ega bo'lmasligi kerak — u faqat State maydonlarining joriy qiymatlari asosida interfeysni tavsiflaydi.
didUpdateWidget ota-ona StatefulWidget-ni yangi parametrlar bilan qayta qurganda chaqiriladi. State eski vidjetga oldWidget orqali kirish imkoniyatiga ega bo'ladi va uni yangisi bilan solishtirishi mumkin. Agar parametrlar o'zgargan bo'lsa, holatni yangilash, yangi ma'lumotlarni yuklash yoki animatsiyani qayta boshlash mumkin.
dispose — barcha resurslar bo'shatiladigan yakuniy metod: kontrollerlar, obunalar, taymerlar. dispose-dan keyin State o'lik deb belgilanadi: mounted false qaytaradi, setState chaqiruvi istisno chiqaradi. Metodning oxirgi qatorida super.dispose() chaqiruvi majburiydir.
| Metod | Qachon chaqiriladi | Majburiy super |
|---|---|---|
| initState | State yaratilganda | Ha, birinchi qatorda |
| didChangeDependencies | initState-dan keyin va InheritedWidget o'zgarganda | Ha |
| build | initState, didChangeDependencies, setState-dan keyin | Yo'q |
| didUpdateWidget | Otadan yangi vidjet kelganda | Ha |
| setState | Dasturchi chaqiruvi bilan | Yo'q |
| dispose | Daraxtdan o'chirilganda | Ha, oxirgi qatorda |
State ning ishlash mexanizmi uchta asosiy prinsipga asoslanadi: Element bilan bog'lanish, setState orqali reaktivlik va widget xususiyati orqali ota-onaga kirish. Flutter elementlar daraxtini qurayotganda StatefulElement-ga duch kelganda, bog'langan vidjetning createState-ni chaqiradi. Yaratilgan State elementda saqlanadi va element o'chirilgunga qadar mavjud bo'ladi.
setState chaqirilganda State o'zini «iflos» (dirty) deb belgilaydi va keyingi kadrda qayta qurishni rejalashtiradi. Muhim: setState build-ni darhol chaqirmaydi — u faqat qayta qurish zarurligini qayd etadi. Flutter joriy kadrdagi barcha iflos elementlarni to'playdi va ularni guruhli ravishda qayta quradi, bu esa ishlashni optimallashtiradi. build chaqiruvidan so'ng State «toza» (clean) holatiga qaytadi.
widget xususiyati State-ga StatefulWidget konstruktoriga uzatilgan parametrlarni o'qish imkonini beradi. StatefulWidget o'zgarmas bo'lgani uchun (StatelessWidget kabi), uning maydonlari o'zgarmaydi — parametrlar o'zgarganda ota-ona yangi vidjet yaratadi, State esa uni didUpdateWidget orqali oladi. Bu State-ning har doim ota-onaning dolzarb ma'lumotlari bilan ishlashini kafolatlaydi.
Taymer bilan o'zgaruvchan maydonga ega asosiy State misoli. initState, setState va dispose-ni ko'rsatadi:
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 soniya o'tdi');
}
}
Ota-ona parametrlariga kirish va didUpdateWidget orqali ularning o'zgarishlariga reaksiya uchun widget xususiyatidan foydalanish misoli:
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('Salom, $_displayName!');
}
}
Ikkinchi misolda State kirish parametri name o'zgarishini kuzatadi va faqat haqiqiy o'zgarish bo'lganda ko'rinishni qayta formatlaydi. widget.name != oldWidget.name tekshiruvisiz, metod ota-onaning har bir qayta qurilishida, hatto nom o'zgarmagan bo'lsa ham chaqirilardi — bu framework uchun ortiqcha ish.
State va StatefulWidget Flutter arxitekturasida turli rollarni bajaradigan ikki xil sinfdir. StatefulWidget — vidjet konfiguratsiyasini tavsiflaydigan va State yaratadigan engil o'zgarmas qobiq. State — o'zgaruvchan ma'lumotlarni saqlaydigan, obunalarni boshqaradigan va UI quradigan og'ir obyekt. Bu bo'linish Flutter-ga holatni yo'qotmasdan vidjetlarni yo'q qilish va yaratish imkonini beradi.
StatefulWidget-ning barcha maydonlari final bo'lishi va konstruktorda o'rnatilishi kerak — ular yaratilgandan keyin o'zgarmaydi. State, aksincha, istalgan vaqtda o'z maydonlarini o'zgartirishi mumkin, ammo barcha o'zgarishlar setState chaqiruvi bilan birga bo'lishi kerak, shunda Flutter qayta qurish zarurligini bilib oladi. Bu asosiy farq: StatefulWidget — «nimani ko'rsatish», State — «qanday ko'rsatish va qanday ma'lumotlardan foydalanish».
Flutter source code analysis-ga (Flutter SDK, 2026) ko'ra, StatefulWidget faqat bitta majburiy maydonni o'z ichiga oladi — createState, holbuki State BuildContext-ga kirish imkoniyatiga ega, oqimlarga obuna bo'lishi, animatsiyalar va kontrollerlarni boshqarishi mumkin. StatefulWidget-ni imkon qadar sodda saqlash, barcha mantiqni State-ga o'tkazish tavsiya etiladi.
Widget va State-ni ajratish konfiguratsiyaning o'zgarmasligini ta'minlaydigan arxitektura qaroridir. Agar StatefulWidget o'zi holatni saqlasa, ota-onaning har bir qayta qurilishida holat yo'qolardi. Holatni alohida obyektga chiqarish orqali Flutter ma'lumotlarning qayta qurilishlardan omon qolishini, vidjetlarning esa engil va solishtirish mumkin bo'lib qolishini kafolatlaydi.
State obyekti izolyatsiya qilingan — boshqa vidjetlarning State-iga to'g'ridan-to'g'ri kirish imkoniyati yo'q. Vidjetlar o'rtasida ma'lumot almashish uchun InheritedWidget yoki tashqi holat boshqarish vositalari ishlatiladi: Provider, Riverpod, Bloc, Redux. Har bir yondashuv masalani o'ziga xos tarzda hal qiladi: InheritedWidget vidjetlar daraxti orqali ishlaydi, Provider — DI konteyneri orqali, Bloc — hodisa oqimlari orqali.
Vositani tanlash loyiha hajmiga bog'liq. Kichik dastur uchun InheritedWidget va mahalliy State yetarli. O'rta va katta loyiha uchun Riverpod yoki Bloc tavsiya etiladi — ular sinovdan o'tkazish qulayligi, bashorat qilish imkoniyati va mantiqni UI-dan ajratishni ta'minlaydi. State esa faqat vidjetning mahalliy ma'lumotlari (fokus, skroll, animatsiya) uchun ishlatiladi.
Flutter Community Survey 2025-ga (Flutter Foundation, dekabr 2025) ko'ra, Riverpod yangi loyihalarda holatni boshqarish uchun eng mashhur yechimdir (38%), undan keyin Bloc (31%) va Provider (22%). Har uchala vosita State bilan mos keladi va standart hayot aylanishidan voz kechishni talab qilmaydi.
Birinchi xato — asinxron callback-da setState-dan oldin mounted-ni tekshirishni unutish. Vidjet daraxtdan o'chirilganda (masalan, foydalanuvchi ekranni tark etdi), lekin asinxron operatsiya (HTTP so'rovi) hali bajarilayotganda, uning tugashidan keyin State allaqachon o'lik. O'lik State-da setState chaqiruvi istisno chiqaradi. if (mounted) setState(...) tekshiruvi muammoni hal qiladi.
Ikkinchi xato — InheritedWidget bog'liqliklarini didChangeDependencies o'rniga initState-da sozlash. initState-da kontekst hali o'rnatilmagan, shuning uchun MediaQuery.of(context) istisno chiqaradi. InheritedWidget-dan barcha bog'liqliklar didChangeDependencies yoki build-da sozlanishi kerak.
Uchinchi xato — setState chaqirmasdan maydonlarni o'zgartirish. Dasturchi setState-siz State maydonini o'zgartirsa, Flutter o'zgarishdan xabar topmaydi va UI yangilanmaydi. Masalan: _list.add(item) keyingi setState((){}) holda ro'yxatni o'zgartiradi, lekin ekran bir xil qoladi.
State-da asinxron operatsiyalar uchun xavfsizlik namunasi:
Future<void> _fetchData() async {
final data = await ApiService.fetch();
if (mounted) {
setState(() => _data = data);
}
}
mounted tekshiruvi setState faqat tirik State uchun chaqirilishini kafolatlaydi, «setState called after dispose» istisnosining oldini oladi.
Tez-tez so'raladigan savollar
StatefulWidget — vidjetning o'zgarmas konfiguratsiyasi, State esa ma'lumotlarni saqlaydigan va hayot aylanishini boshqaradigan o'zgaruvchan obyektdir. Vidjet qayta yaratilishi mumkin, State — yo'q. StatefulWidget createState orqali State yaratadi.
Aynan bitta. createState metodi StatefulWidget daraxtga birinchi marta joylashtirilganda bir marta chaqiriladi. Ota-ona bir necha marta qayta qurilsa ham, State obyekti bir xil qoladi, vidjetning turi yoki Key o'zgarmaguncha.
mounted — State vidjetlar daraxtida mavjudligini ko'rsatuvchi mantiqiy bayroqdir. dispose chaqiruvidan keyin mounted false bo'ladi. Asinxron callback-larda setState-dan oldin tekshirish uchun ishlatiladi, istisnoni oldini olish uchun.
Yo'q. State har doim muayyan StatefulWidget bilan generik orqali bog'lanadi: State<T extends StatefulWidget>. State-ni to'g'ridan-to'g'ri, vidjet bilan bog'lanmasdan yaratish arxitektura jihatdan mumkin emas.
Istisno chiqariladi: «setState called after dispose». dispose chaqiruvidan keyin State o'lik hisoblanadi va UI-ni setState orqali qayta qurishga urinishlar taqiqlanadi. Yechim — har bir setState-dan oldin mounted-ni tekshiring.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.