Ответ
setState() — это метод класса State, который сообщает фреймворку Flutter, что внутреннее состояние виджета изменилось и его представление (build метод) требует актуализации.
Механика работы:
- Вызов: Внутри переданной callback-функции вы изменяете данные (например,
_counter++). - Пометка:
setStateпомечает связанныйStateобъект как "грязный" (dirty). - Планирование: Фреймворк планирует перестройку (rebuild) этого виджета на следующем кадре.
- Перестройка: На этапе построения (build phase) фреймворк вызывает метод
buildу этогоState, который возвращает новое дерево виджетов на основе обновленного состояния. - Сравнение: Flutter сравнивает новое дерево виджетов с предыдущим (процесс diffing) и минимально обновляет RenderObject дерево в нужных местах.
Пример и важные нюансы:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<String> _items = [];
void _incrementCounter() {
// ПРАВИЛЬНО: Изменение состояния внутри callback.
setState(() {
_counter++;
});
}
void _addItem(String item) {
// ОШИБКА: setState вызван после асинхронной операции, состояние уже изменено.
_items.add(item); // Изменение до setState!
setState(() {}); // Пустой callback — антипаттерн.
}
Future<void> _fetchData() async {
final data = await apiService.loadData();
// ПРАВИЛЬНО: Все изменения состояния — внутри callback.
setState(() {
_items = data;
});
}
}
Ключевые правила:
- Только в StatefulWidget: Вызывается только из объекта
State. - Синхронный callback: Функция внутри
setStateдолжна быть синхронной. Асинхронные операции выполняются до или после. - Не во время build: Вызов
setStateнепосредственно из методаbuildприведет к циклической перестройке и ошибке. - Для сложного состояния: При управлении состоянием всего приложения (например, данными пользователя) предпочтительны специализированные решения (Provider, Riverpod, Bloc), которые отделяют логику состояния от UI и предоставляют более тонкий контроль над перерисовками.