Ответ
Жизненный цикл StatefulWidget управляется его ассоциированным объектом State. Основные этапы:
- createState(): Вызывается фреймворком при вставке виджета в дерево. Создает экземпляр класса
State. - initState(): Вызывается один раз сразу после
createState(). Идеальное место для инициализации данных, подписки на Stream'ы или создания контроллеров (например,AnimationController,ScrollController).@override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(seconds: 1), ); _dataStreamSubscription = myService.dataStream.listen(_updateData); } - didChangeDependencies(): Вызывается после
initState()и при изменении зависимостей виджета (например, когда обновилсяInheritedWidget, на который он подписан черезcontext.dependOnInheritedWidgetOfExactType). - build(): Вызывается многократно для построения UI в ответ на
setState()или изменения внешних данных. Должен быть чистой функцией от состояния (State) и свойств (widget.someProp). - didUpdateWidget(oldWidget): Вызывается, когда родительский виджет перестраивается и создает новый экземпляр
StatefulWidgetс тем жеruntimeType, но этотStateобъекта переиспользуется. Позволяет сравнивать старые и новые свойства (oldWidgetvswidget).@override void didUpdateWidget(MyWidget oldWidget) { super.didUpdateWidget(oldWidget); if (widget.itemId != oldWidget.itemId) { _loadNewItem(widget.itemId); } } - setState(): Метод для уведомления фреймворка об изменении внутреннего состояния. Вызывает перестроение виджета через
build(). - deactivate(): Вызывается, когда
Stateудаляется из дерева, но может быть повторно вставлен в другое место дерева (например, внутриGlobalKey). - dispose(): Вызывается, когда
Stateобъект удаляется навсегда. Критически важно освобождать ресурсы: отменять таймеры, закрывать контроллеры, отписываться от Stream'ов.@override void dispose() { _animationController.dispose(); // Обязательно! _dataStreamSubscription.cancel(); super.dispose(); }
Важно: После вызова dispose(), свойство mounted становится false. Любой последующий вызов setState() выбросит исключение.