StatefulWidget — dəyişən vəziyyətə malik Flutter vidjetidir, UI-nin istifadəçi hərəkətlərinə, asinxron hadisələrə və məlumat axınlarına reaksiya verməsinə imkan verir. Rəsmi Flutter sənədlərinə (Flutter.dev, 2026) görə, StatefulWidget tətbiqin bütün interaktiv elementləri üçün istifadə olunur: giriş formaları, animasiyalar, seçim qutuları, keçid açarları şəbəkədən məlumat yükləyən ekranlar. StatelessWidget-dən fərqli olaraq, o, bütün həyat dövrü boyunca saxlanılan və vidjetin özünü yenidən yaratmadan yenidən qurula bilən ayrıca State obyekti yaradır.
Əsas məqamlar
StatefulWidget — istifadəçi hərəkətlərinə, sistem hadisələrinə və ya asinxron əməliyyatlara cavab olaraq öz vəziyyətini dəyişə bilən Flutter sinifidir. StatelessWidget-dən fərqli olaraq, StatefulWidget birbaşa göstərilmir — o, göstərilməyə cavabdeh olan State obyekti yaradır. Iki sinifə (Widget və State) bölünmə Flutter-ə vidjetin özünü yenidən yaratmadan UI-ni yenidən qurmağa imkan verir ki, bu da tez-tez yenilənmələrdə əhəmiyyətli performans üstünlüyü verir.
StatefulWidget memarlığı «dəyişən və dəyişməyənin ayrılması» nümunəsinə əməl edir: vidjetin özü dəyişməz qalır (StatelessWidget kimi), bütün dəyişən vəziyyət isə ayrı State obyektində saxlanılır. Bu, Flutter-ə vidjetləri növünə və açarına görə müqayisə edərək təkrar istifadə etməyə və eyni zamanda yenidən qurmalar arasında aktual vəziyyəti qorumağa imkan verir.
Google-a görə (Flutter Architectural Overview, 2026), StatefulWidget vəziyyətin vidjetin ömrü boyunca bir dəfədən çox dəyişdyi ssenarilər üçün optimaldır: mətn sahələri, animasiyalar, taymerlər, məlumat axınları, asinxron yükləmələr. Tək dəfəlik başlatma üçün StatelessWidget kifayətdir.
StatefulWidget vidjet xarici hadisələrə reaksiya verməli olduqda məcburidir: düyməyə basma, HTTP sorğusunun tamamlanması, verilənlər bazasından məlumat yenilənməsi, WebSocket-ə abunə. O, həmçinin animasiyalı vidjetlər, kontrollerli mətn sahələri və foku idarə edən komponentlər üçün də zəruridir. Əgər vidjet yalnız məlumatı göstərir və hadisə yaratmırsa — StatelessWidget istifadə edin.
StatefulWidget iki sinifdən ibarətdir: StatefulWidget (yüngül, dəyişməz) və State (ağır, dəyişən). Framework ağaca yerləşdirilərkən bir dəfə çağırılan createState() metodu vasitəsilə State yaradır. State widget xassəsi vasitəsilə vidjetə istinad alır və həyat dövriünün istənilən anında onun sahələrinə müraciət edə bilər.
Həyat dövriü StatefulWidget altı əsas mərhələdən ibarətdir, hər biri müəyyən tapşırıqları yerinə yetirmək üçün dəyişdirilə bilən metodu təmin edir. Bu mərhələləri başa düşmək resurslarla düzgün işləmək və yaddaş sızıntılarından qaçmaq üçün kritik əhəmiyyət daşıyır.
createState — həyat dövriünün ilk metodu, StatefulWidget ağaca yerləşdirilərkən çağırılır. O, bu vidjetlə əlaqəli yeni State nümunəsini qaytarmalıdır. Bu metod elementin bütün ömrü boyunca dəqiq bir dəfə çağırılır. Burada ağır əməliyyatlar yerinə yetirməmək vacibdir — createState mümkün qədər yüngül olmalıdır.
initState — State yaradıldıqdan dərhal sonra, ilk UI qurulmasından əvvəl çağırılır. Burada yerinə yetirilir: kontrollerlərin başlatılması (TextEditingController, AnimationController), məlumat axınlarına abunə (StreamSubscription), taymerlərin qurulması və sahələrin ilkin başlatılması. Flutter sənədlərinə (Flutter.dev, 2026) görə, initState-də BuildContext.of() çağırıla bilməz — ağac hələ tam qurulmayıb.
didChangeDependencies — initState-dən sonra və InheritedWidget asılılıqları hər dəyişəndə çağırılır. Bu, MediaQuery.of(context) çağırmaq və ya Theme-ə abunə olmaq üçün uyğun yerdir — tətbiq işləyərkən dəyişə bilən dəyərlər. Əgər vidjet InheritedWidget istifadə edirsə, başlatma məntiqi burada olmalıdır, initState-də yox.
build — vidjetlər ağacını qaytaran əsas metod. initState-dən sonra, didChangeDependencies-dən sonra və hər setState-dən sonra çağırılır. didUpdateWidget valideyn yenidən qurulduqda və StatefulWidget-ə yeni parametrlər ötürdükdə çağırılır. Burada köhnə və yeni vidjet sahələrini müqayisə edə və zərurət olduqda vəziyyəti yeniləyə bilərsiniz.
dispose — həyat dövriünün son mərhələsidir. Burada bütün resurslar azad edilir: axınlardan çıxılır, kontrollerlər silinir, taymerlər ləğv edilir. dispose-un çağırılmaması yaddaş sızıntılarına gətirib çıxarır. Dispose-dan sonra State ölü sayılır — onun içərisində setState çağırmaq istisna yaradır.
StatefulWidget-in işləmə mexanizmi üç varlığın əlaqələndirilmiş işinə əsaslanır: Widget (yüngül təsvir), Element (aralıq qat) və State (məlumat anbarı). Flutter təsvirdə StatefulWidget ilə qarşılaşdıqda, createState çağıran və State obyektinə istinad saxlayan StatefulElement yaradır. Valideyn yenidən qurulduqda, Flutter yeni vidjeti cari Element ilə müqayisə edir — əgər növ və Key uyğun gəlirsə, Element yenilənir, State isə eyni qalır.
Vəziyyət yalnız setState çağırılması ilə dəyişir, framework-a yenidən qurma ehtiyacı barədə məlumat verir. Anlamaq vacibdir: setState vəziyyəti avtomatik dəyişmir — o, yalnız vidjeti «çirkli» olaraq qeyd edir. Tərtibatçı setState-ə ötürülən geri çağırışda State sahələrini özü yeniləyir. Geri çağırış tamamlandıqdan sonra Flutter build çağırır və UI-ni yeniləyir.
Dart/Flutter komandasına görə (Dart Language Specification, 2026), bu bölgü bütün vəziyyət dəyişikliklərinin build çağırılmazdan əvvəl sinxron baş verməsini təmin edir və UI-nin qismən yenilənmiş məlumatları göstərməsi vəziyyətini aradan qaldırır. Bu, Flutter-də interfeys ardıcıllığının əsas mexanizmidir.
Sadə bir StatefulWidget nümunəsinə baxaq — düymə kliklərinin sayıcısı. O, əsas nümunəni nümayiş etdirir: State yaratma, initState-də sahəni başlatma, setState vasitəsilə dəyişiklik:
class CounterScreen extends StatefulWidget {
const CounterScreen({super.key});
@override
State<CounterScreen> createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Say: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('Artır'),
),
],
);
}
}
Asinxron məlumat yükləmə və həyat dövriünün idarə edilməsi nümunəsi. StatefulWidget şəbəkədən məlumat yükləyir və yükləmə vəziyyətini göstərir:
class UserProfilePage extends StatefulWidget {
final String userId;
const UserProfilePage({super.key, required this.userId});
@override
State<UserProfilePage> createState() => _UserProfilePageState();
}
class _UserProfilePageState extends State<UserProfilePage> {
UserModel? _user;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadUser();
}
Future<void> _loadUser() async {
final user = await UserService.fetchUser(widget.userId);
setState(() {
_user = user;
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
if (_isLoading) return const CircularProgressIndicator();
return Text('Salam, ${_user!.name}');
}
}
Ikinci nümunədə qeyd etmək vacibdir: initState asinxron əməliyyatı başlatır, lakin metodun özü asinxron deyil. Asinxronluq async/await vasitəsilə ayrıca _loadUser metodu içərisində húyata keçirilir, sorğu tamamlandıqdan sonra setState vasitəsilə vəziyyəti yeniləyir. Bu yanaşma vidjetin məlumatları almazdan əvvəl yükləmə göstəricisini düzgün göstərməsini təmin edir.
StatefulWidget və StatelessWidget arasında seçim yalnız vəziyyətin olması məsələsi deyil. StatefulWidget initState, didChangeDependencies, didUpdateWidget və dispose metodları ilə tam həyat dövriü təmin edir ki, bu da kontrollerlər, animasiyalar və axınlarla işləmək üçün zəruridir. StatelessWidget isə bu metodlara malik deyil və framework üçün həmişə yüngül çəkiyə malikdir.
Flutter komandasının tövsiyyəsi (Flutter docs, 2026) — tətbiqdə StatefulWidget sayını minimuma endirmək, vəziyyəti ağacda yuxarı qaldıraraq (State Hoisting) və ya vəziyyətin idarə edilməsi həllərindən (Riverpod, Bloc, Provider) istifadə etmək. Hər bir StatefulWidget element silinənə qədər yaşayan State obyekti yaradır — belə vidjetlər nə qədər çox olarsa, yaddaş yükü bir o qədər yüksək olar.
| Meyar | StatefulWidget | StatelessWidget |
|---|---|---|
| Vəziyyət | Dəyişən | Dəyişməz |
| Həyat dövriü | 6 mərhələ | Yalnız build |
| State obyekti | Ayrıca yaradılır | Tələb olunmur |
| setState | Mövcuddur | Mövcud deyil |
| Abunələr | initState/dispose | Dəstəklənmir |
| const konstruktor | Məhdud | Tam dəstəklənir |
| Yaddaş istehlakı | Daha çox | Daha az |
StatefulWidget State obyektinin yaradılması və saxlanması zərurəti səbəbindən StatelessWidget-dən daha çox resurs tələb edir. Lakin bir neçə qaydaya əməl edərsə, StatefulWidget-dən düzgün istifadə performans problemlərinə gətirib çıxarmaz. Birincisi, StatefulWidget-in dərin iç-içə yerləşdirilməsindən qaçın — hər səviyyə ağacın gəzilməsinə əlavə yük gətirir. Ikincisi, mürəkkəb StatefulWidget-ı hər biri öz vəziyyət hissəsinə cavabdeh olan bir neçə sadə vidjetə bölün.
Flutter Performance tədqiqatına görə (Flutter.dev, fevral 2026), FPS düşməsinin ən tez-tez səbəbi valideyn vidjetdə setState çağırmaqdır ki, bu da göstərimini dəyişməyən StatelessWidget daxil olmaqla bütün törəmələri yenidən qurur. Həll yolu — dəyişən UI hissəsini ayrı StatefulWidget-ə çıxarmaq ki, setState yalnız zəruri vidjetlərin minimumunu yenidən qursun.
State daxilində const istifadəsi digər vacib texnikadır. Əgər törəmə vidjetlər const olaraq elan edilərsə, Flutter valideyndə setState çağırıldıqda onları yenidən qurmayacaq. Bu, framework yükünü azaldır və kadr çəkmə vaxtını qısaldır.
Hər setState çağırışı vidjetin tam yenidən qurulmasına səbəb olur. Əgər vəziyyət yüksək tezliklə dəyişirsə (məsələn, animasiya və ya məlumat axını), əl ilə setState çağırmaq əvəzinə AnimatedBuilder, ValueListenableBuilder və ya StreamBuilder istifadə etməyi düşünün. Bu vidjetlər yenidən qurmanı optimallaşdırır, yalnız həqiqətən dəyişən UI hissəsini yeniləyir.
StatefulWidget ilə ilk tipik səhv — dispose-dan sonra setState çağırmaqdır. Vidjet ağacdan silindikdə, State ölü sayılır və hər setState çağırışı «setState called after dispose» istisnası yaradır. Ən çox bu, asinxron əməliyyat vidjet silindikdən sonra tamamlandıqda baş verir. Həll yolu — setState çağırmazdan əvvəl mounted bayrağını yoxlamaq və ya dispose-da asinxron əməliyyatları ləğv etmək.
Ikinci səhv — build metodunda ağır hesablamalar aparmaqdır. Build hər setState və valideynin hər yenidən qurulması zamanı çağırıldığı üçün, bütün hesablamalar mümkün qədər yüngül olmalıdır. Əgər resurs tutumlu əməliyyat yerinə yetirmək lazımdırsa — onu ayrı Isolate-ə çıxarın və ya nəticəni State sahəsində keşləyin.
Üçüncü səhv — super.initState() və super.dispose() çağırılmamasıdır. Bu metodları dəyişdirərkən, tərtibatçı valideyn tətbiqini çağırmağa borcludur. Əgər bu edilməzsə, framework Element vəziyyətini düzgün idarə edə bilməz və bu, çətin aşkarlanan xətalara gətirib çıxarar.
mounted yoxlayınsuper.initState() və super.dispose() çağırmağı unutmayınTez-tez verilən suallar
StatefulWidget setState vasitəsilə öz vəziyyətini dəyişə bilər, həyat dövriünə (initState, dispose) malikdir və ayrı State obyekti yaradır. StatelessWidget vəziyyəti dəyişə bilməz və həyat dövriü metodlarına malik deyil — o, sadəcə ötürülən məlumatları göstərir.
createState hər StatefulElement nümunəsi üçün dəqiq bir dəfə çağırılır. Valideyn dəfələrlə yenidən qurulsa belə, vidjetin növü və Key dəyişmədikcə, createState çağırılmır — mövcud State obyekti istifadə olunur.
Resurslar azad edilməyəcək: kontrollerlər fonda işləməyə davam edəcək, axın abunəlikləri aktiv qalacaq, taymerlər ləğv edilməyəcək. Bu, yaddaş sızıntılarına gətirib çıxarır və dispose-dan sonra setState çağırılmasına səbəb ola bilər ki, bu da istisna yaradır.
Bəli, konstruktor StatefulWidget const ola bilər. Lakin bu, StatelessWidget üçün olduğu kimi eyni fayda vermir — State obykti yenə də ilk yerləşdirilmədə yaradılacaq. const yalnız vidjetin özünə (yüngül qapağa) təsir edir, State-ə yox.
didUpdateWidget valideyn StatefulWidget-ə yeni parametrlər ötürdükdə çağırılır. Bu, vəziyyəti yeni məlumatlarla sinxronlaşdırmaq üçün lazımdır — məsələn, parametrlərdə userId dəyişərsə, yeni istifadəçinin profilini yükləmək lazımdı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