← Назад к вопросам

Если меняются данные в InheritedWiget то какой callback будет вызываться у state?

2.0 Middle🔥 181 комментариев
#Flutter виджеты#State Management

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Callbacks при изменении данных в InheritedWidget

Когда данные в InheritedWidget изменяются, Flutter использует специальный механизм для оповещения зависимых виджетов. В State вызывается метод didChangeDependencies().

Основной механизм

didChangeDependencies()

Это основной callback, который вызывается когда меняются зависимости виджета, включая изменения в InheritedWidget:

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Вызывается когда меняются зависимости (InheritedWidget)
    print('InheritedWidget изменился!');
  }
  
  @override
  Widget build(BuildContext context) {
    final data = context.watch<MyInheritedWidget>();
    return Text(data.value);
  }
}

Жизненный цикл вызовов

1. initState() — вызывается один раз при создании State
2. didChangeDependencies() — вызывается при создании и при изменении зависимостей
3. build() — вызывается после didChangeDependencies()
4. dispose() — вызывается при удалении State

Практический пример с InheritedWidget

// InheritedWidget
class ThemeData extends InheritedWidget {
  final String theme;
  final int updateCount;
  
  const ThemeData({
    required this.theme,
    required this.updateCount,
    required super.child,
  });
  
  @override
  bool updateShouldNotify(ThemeData oldWidget) {
    return theme != oldWidget.theme || updateCount != oldWidget.updateCount;
  }
}

// Consumer Widget
class MyConsumerWidget extends StatefulWidget {
  @override
  State<MyConsumerWidget> createState() => _MyConsumerWidgetState();
}

class _MyConsumerWidgetState extends State<MyConsumerWidget> {
  @override
  void initState() {
    super.initState();
    print('initState вызван');
  }
  
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('didChangeDependencies вызван - данные в InheritedWidget изменились!');
  }
  
  @override
  Widget build(BuildContext context) {
    final themeData = context.dependOnInheritedWidgetOfExactType<ThemeData>();
    print('build вызван с темой: ${themeData?.theme}');
    
    return Text('Тема: ${themeData?.theme ?? "default"}');
  }
}

Важные методы работы с InheritedWidget

context.dependOnInheritedWidgetOfExactType()

Вызывает didChangeDependencies() при изменении данных:

final themeData = context.dependOnInheritedWidgetOfExactType<ThemeData>();
// didChangeDependencies() будет вызван когда themeData изменится

context.watch() (Provider pattern)

Современный способ с тем же результатом:

final data = context.watch<MyInheritedWidget>();
// didChangeDependencies() будет вызван при изменении

context.read() (без подписки)

Получает значение БЕЗ создания зависимости:

final data = context.read<MyInheritedWidget>();
// didChangeDependencies() НЕ будет вызван

updateShouldNotify()

Этот метод в InheritedWidget определяет, нужно ли перестраивать зависимые виджеты:

class CounterInheritedWidget extends InheritedWidget {
  final int count;
  
  const CounterInheritedWidget({
    required this.count,
    required super.child,
  });
  
  @override
  bool updateShouldNotify(CounterInheritedWidget oldWidget) {
    // Если count изменился — вернуть true
    // Это вызовет didChangeDependencies() у зависимых виджетов
    return count != oldWidget.count;
  }
}

Порядок вызовов при изменении InheritedWidget

1. InheritedWidget.updateShouldNotify() возвращает true
2. didChangeDependencies() вызывается у всех зависимых State
3. build() вызывается у зависимых виджетов
4. UI обновляется

Практика: оптимизация с didChangeDependencies()

class _UserScreenState extends State<UserScreen> {
  late User currentUser;
  
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Получаем данные один раз при изменении
    currentUser = context.watch<UserProvider>().user;
    print('Пользователь изменился: ${currentUser.name}');
  }
  
  @override
  Widget build(BuildContext context) {
    // Используем уже полученные данные
    return Text('Привет, ${currentUser.name}!');
  }
}

Итого

Основной callback: didChangeDependencies() — вызывается когда меняются InheritedWidget данные, на которые подписан виджет. Это ключевой метод для реакции на изменения в InheritedWidget без пересоздания State.

Если меняются данные в InheritedWiget то какой callback будет вызываться у state? | PrepBro