State — Flutter-də məlumat idarəetməsinin mərkəzi obyekti, StatefulWidget ilə əlaqəli və dəyişən məlumatların saxlanmasına və interfeysin qurulmasına cavabdehdir. Flutter rəsmi sənədlərinə görə (Flutter.dev, 2026), State vidjetin bütün həyat dövrü boyunca mövcuddur və onun yenidən qurulmalarından sağ çıxır, UI yeniləmələri arasında məlumat ardıcıllığını təmin edir. Vidjetin özündən fərqli olaraq, State öz sahələrini dəyişə bilər və setState çağırışı vasitəsilə yenidən qurulmanı başlada bilər.
Əsas məqamlar
State — Flutter arxitekturasında StatefulWidget-in dəyişən məlumatlarını saxlayan və bu məlumatların interfeysdə necə göstərildiyini müəyyən edən obyektdir. Hər bir StatefulWidget ağaca yerləşdirilərkən createState metodu vasitəsilə dəqiq bir State obyekti yaradır. State vidjetdən asılı olmayaraq mövcuddur: valideyn StatefulWidget-i yeni parametrlərlə yenidən qurarsa, State eyni qalır və yenilənmiş vidjeti widget xassəsi vasitəsilə alır.
Flutter Architectural Overview-ə (Google, 2026) görə, Widget və State-in ayrılması framework-a ağac elementlərini təkrar istifadə etməyə imkan verən şüurlu arxitektura qərarıdır. Vidjet (yüngül təsvir) dəfələrlə yaradılıb məhv edilə bilər, lakin State (məlumatları olan ağır obyekt) element ağacda olduğu müddətcə yaddaşda qalır. Bu, valideyn vidjetlərin tez-tez yenidən qurulması zamanı məlumat itkisinin qarşısını alır.
State StatefulWidget interfeysini generik vasitəsilə həyata keçirir: class _MyState extends State<MyWidget>. Generik State-i konkret StatefulWidget növü ilə əlaqələndirir və widget xassəsi vasitəsilə onun sahələrinə tip-təhlükəsiz girişi təmin edir.
State obyekti StatefulElement daxilində saxlanılır — Widget və RenderObject arasında aralıq təbəqə. StatefulElement createState vasitəsilə State yaradır, ona istinadı saxlayır və State-i sahib kimi ötürür. Element yalnız vidjet ağacdan silindikdə məhv olur — bu ana qədər State yaddaşda yaşayır.
Həyat dövrü deterministdir və ciddi çağırış ardıcıllığından ibarətdir. Bu ardıcıllığı başa düşmək resurslarla düzgün işləməyin və yaddaş sızmalarının qarşısını almağın əsasıdır.
initState State yaradılarkən birinci çağırılır. Bu metoda kontrollerlər, məlumat axını abunəlikləri, taymerlər və sahələrin ilkin dəyərləri ilkinləşdirilir. Birinci sətirdə super.initState() çağırışı məcburidir. initState mərhələsində vidjet ağacı hələ tam qurulmayıb, ona görə MediaQuery.of(context) kimi metodlar düzgün işləməyə bilər.
didChangeDependencies initState-dən sonra və InheritedWidget asılılıqları hər dəyişdikdə çağırılır. Məhz burada, initState-də yox, MediaQuery.of(context) və ya Theme.of(context) çağırılmalıdır, çünki bu anda ağac artıq qurulub. Bu metod həmçinin vidjet InheritedWidget-in fərqli dəyərlər təqdim etdiyi başqa kontekstə köçürüldükdə də çağırılır.
build — State-in əsas metodu, vidjet ağacını qaytarır. initState-dən sonra, didChangeDependencies-dən sonra və hər setState-dən sonra çağırılır. build metodu yan təsirlərə malik olmamalıdır — o, yalnız State sahələrinin cari dəyərləri əsasında interfeysi təsvir edir.
didUpdateWidget valideyn StatefulWidget-i yeni parametrlərlə yenidən qurduqda çağırılır. State köhnə vidjetə oldWidget vasitəsilə giriş əldə edir və onu yenisi ilə müqayisə edə bilər. Parametrlər dəyişibsə, vəziyyəti yeniləmək, yeni məlumatları yükləmək və ya animasiyanı yenidən başlatmaq olar.
dispose — bütün resursların sərbəst buraxıldığı yekun metod: kontrollerlər, abunəliklər, taymerlər. dispose-dan sonra State ölü kimi qeyd olunur: mounted false qaytarır, setState çağırışı istisna atır. Metodun son sətirində super.dispose() çağırışı məcburidir.
| Metod | Nə vaxt çağırılır | Məcburi super |
|---|---|---|
| initState | State yaradılarkən | Bəli, birinci sətirdə |
| didChangeDependencies | initState-dən sonra və InheritedWidget dəyişdikdə | Bəli |
| build | initState, didChangeDependencies, setState-dən sonra | Xeyr |
| didUpdateWidget | Valideyndən yeni vidjet gəldikdə | Bəli |
| setState | Proqramçının çağırışı ilə | Xeyr |
| dispose | Ağacdan silinərkən | Bəli, son sətirdə |
State-in iş mexanizmi üç əsas prinsipə əsaslanır: Element ilə assosiasiya, setState vasitəsilə reaktivlik və widget xassəsi vasitəsilə valideynə giriş. Flutter element ağacını qurarkən StatefulElement-ə rast gəldikdə, əlaqəli vidjetin createState-ni çağırır. Yaradılmış State elementdə saxlanılır və element silinənə qədər mövcud olur.
setState çağırıldıqda State özünü «çirkli» (dirty) kimi qeyd edir və növbəti kadrda yenidən qurulmanı planlaşdırır. Vacib: setState build-i dərhal çağırmır — o, yalnız yenidən qurulma ehtiyacını qeydiyyata alır. Flutter cari kadrda bütün çirkli elementləri toplayır və onları toplu şəkildə yenidən qurur ki, bu da performansı optimallaşdırır. build çağırışından sonra State «təmiz» (clean) vəziyyətinə qayıdır.
widget xassəsi State-ə StatefulWidget konstruktoruna ötürülən parametrləri oxumağa imkan verir. StatefulWidget dəyişməz olduğundan (StatelessWidget kimi), onun sahələri dəyişmir — parametrlər dəyişdikdə valideyn yeni vidjet yaradır, State isə onu didUpdateWidget vasitəsilə alır. Bu, State-in həmişə valideynin aktual məlumatları ilə işləməsini təmin edir.
Taymerlə dəyişən sahəsi olan əsas State nümunəsi. initState, setState və dispose-u göstərir:
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 saniyə keçdi');
}
}
Valideyn parametrlərinə giriş və didUpdateWidget vasitəsilə onların dəyişikliklərinə reaksiya üçün widget xassəsindən istifadə nümunəsi:
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('Salam, $_displayName!');
}
}
İkinci nümunədə State giriş parametri name-in dəyişməsini izləyir və yalnız real dəyişiklik olduqda göstərilməni yenidən formatlaşdırır. widget.name != oldWidget.name yoxlaması olmadan metod valideynin hər yenidən qurulmasında çağırılardı, hətta ad dəyişməsə belə — bu framework üçün artıq işdir.
State və StatefulWidget Flutter arxitekturasında müxtəlif rolları yerinə yetirən iki fərqli sinifdir. StatefulWidget — vidjetin konfiqurasiyasını təsvir edən və State yaradan yüngül dəyişməz qabıqdır. State — dəyişən məlumatları saxlayan, abunəlikləri idarə edən və UI quran ağır obyektdir. Bu bölgü Flutter-ə vəziyyət itkisi olmadan vidjetləri məhv etməyə və yaratmağa imkan verir.
StatefulWidget-in bütün sahələri final olmalı və konstruktorda təyin edilməlidir — onlar yaradıldıqdan sonra dəyişmir. State, əksinə, istənilən anda öz sahələrini dəyişə bilər, lakin bütün dəyişikliklər setState çağırışı ilə əvvəlcədən qeyd edilməlidir ki, Flutter yenidən qurulma ehtiyacından xəbər tutsun. Bu əsas fərqdir: StatefulWidget — «nə göstərmək», State — «necə göstərmək və hansı məlumatları istifadə etmək».
Flutter source code analysis-ə (Flutter SDK, 2026) görə, StatefulWidget yalnız bir məcburi sahə ehtiva edir — createState, halbuki State BuildContext-ə giriş əldə edə, axınlara abunə ola, animasiyaları və kontrollerləri idarə edə bilər. StatefulWidget-i mümkün qədər sadə saxlamaq, bütün məntiqi State-ə köçürmək tövsiyə olunur.
Widget və State-in ayrılması konfiqurasiyanın dəyişməzliyini təmin edən arxitektura qərarıdır. Əgər StatefulWidget özü vəziyyəti saxlasaydı, valideynin hər yenidən qurulmasında vəziyyət itirilərdi. Vəziyyəti ayrıca obyektə çıxarmaqla Flutter məlumatların yenidən qurulmalardan sağ çıxmasını, vidjetlərin isə yüngül və müqayisə edilə bilən qalmasını təmin edir.
State obyekti təcrid olunub — digər vidjetlərin State-inə birbaşa girişi yoxdur. Vidjetlər arasında məlumat mübadiləsi üçün InheritedWidget və ya xarici vəziyyət idarəetmə alətlərindən istifadə olunur: Provider, Riverpod, Bloc, Redux. Hər yanaşma məsələni özünəməxsus şəkildə həll edir: InheritedWidget vidjet ağacı vasitəsilə işləyir, Provider — DI konteyneri vasitəsilə, Bloc — hadisə axınları vasitəsilə.
Alətin seçimi layihənin miqyasından asılıdır. Kiçik bir tətbiq üçün InheritedWidget və yerli State kifayətdir. Orta və böyük layihə üçün Riverpod və ya Bloc tövsiyə olunur — onlar test edilə bilənlik, proqnozlaşdırıla bilənlik və məntiqin UI-dən ayrılmasını təmin edir. State isə yalnız vidjetin yerli məlumatları üçün istifadə olunur (fokus, skroll, animasiya).
Flutter Community Survey 2025-ə (Flutter Foundation, dekabr 2025) görə, Riverpod yeni layihələrdə vəziyyət idarəetməsi üçün ən populyar həll yoludur (38%), onu Bloc (31%) və Provider (22%) izləyir. Hər üç alət State ilə uyğundur və standart həyat dövründən imtina tələb etmir.
Birinci səhv — asinxron callback-də setState-dən əvvəl mounted-i yoxlamağı unutmaq. Vidjet ağacdan silindikdə (məsələn, istifadəçi ekranı tərk etdi), lakin asinxron əməliyyat (HTTP sorğusu) hələ icra olunarkən, onun tamamlanmasından sonra State artıq ölüdür. Ölü State-də setState çağırışı istisna atır. if (mounted) setState(...) yoxlaması problemi həll edir.
İkinci səhv — InheritedWidget asılılıqlarını didChangeDependencies əvəzinə initState-də ilkinləşdirmək. initState-də kontekst hələ qurulmayıb, ona görə MediaQuery.of(context) istisna atacaq. InheritedWidget-dən bütün asılılıqlar didChangeDependencies və ya build-də konfiqurasiya edilməlidir.
Üçüncü səhv — setState çağırmadan sahələri mutasiya etmək. Proqramçı setState olmadan State sahəsini dəyişirsə, Flutter dəyişiklikdən xəbər tutmur və UI yenilənmir. Məsələn: _list.add(item) sonrakı setState((){}) olmadan siyahını dəyişəcək, lakin ekran eyni qalacaq.
State-də asinxron əməliyyatlar üçün təhlükəsizlik nümunəsi:
Future<void> _fetchData() async {
final data = await ApiService.fetch();
if (mounted) {
setState(() => _data = data);
}
}
mounted yoxlaması setState-in yalnız canlı State üçün çağırılmasını təmin edir, «setState called after dispose» istisnasının qarşısını alır.
Tez-tez verilən suallar
StatefulWidget — vidjetin dəyişməz konfiqurasiyası, State isə məlumatları saxlayan və həyat dövrünü idarə edən dəyişən obyektdir. Vidjet yenidən yaradıla bilər, State — yox. StatefulWidget createState vasitəsilə State yaradır.
Dəqiq bir. createState metodu StatefulWidget-in ağaca ilk yerləşdirilməsində bir dəfə çağırılır. Valideyn dəfələrlə yenidən qurulsa belə, State obyekti eyni qalır, vidjetin növü və ya Key dəyişməyənə qədər.
mounted — State-in vidjet ağacında olub-olmadığını göstərən məntiqi bayraqdır. dispose çağırışından sonra mounted false olur. Asinxron callback-lərdə setState-dən əvvəl yoxlamaq üçün istifadə olunur, istisnanın qarşısını almaq üçün.
Xeyr. State həmişə konkret StatefulWidget ilə generik vasitəsilə əlaqələndirilir: State<T extends StatefulWidget>. State-i birbaşa, vidjetlə assosiasiya olmadan yaratmaq arxitektura baxımından mümkün deyil.
İstisna atılacaq: «setState called after dispose». dispose çağırışından sonra State ölü hesab olunur və UI-ni setState vasitəsilə yenidən qurmaq cəhdləri qadağandır. Həll yolu — hər setState-dən əvvəl mounted-i yoxlamaqdır.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun