В какой момент можно подписаться на InheritedWidget?

Ответ

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

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  // Получаем экземпляр InheritedWidget и подписываемся на его изменения
  final myData = MyInheritedData.of(context);
  // Здесь можно выполнить действия, зависящие от myData
}

Почему именно здесь? В initState() контекст виджета может быть ещё не готов для корректного поиска InheritedWidget в дереве. didChangeDependencies() гарантирует, что контекст доступен и зависимости актуальны.

Подписка в методе build() также возможна, но это менее эффективно, так как build() вызывается очень часто, что может привести к избыточным операциям.

Ответ 18+ 🔞

А, ну ты про это! Слушай, тут история про подписку на InheritedWidget — как бы не накосячить, чтобы всё работало, а не летело в тартарары.

Так вот, есть у нас метод didChangeDependencies(). Это, бля, твоя главная хата, твой надёжный бункер. Туда и суйся. Он вызывается сразу после initState(), когда виджет только родился, и потом ещё каждый раз, когда какой-нибудь InheritedWidget, от которого ты зависишь, вдруг решит поменяться — ёпта, как погода.

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  // Получаем экземпляр InheritedWidget и подписываемся на его изменения
  final myData = MyInheritedData.of(context);
  // Здесь можно выполнить действия, зависящие от myData
}

А теперь, чувак, главный вопрос: а нахуя именно тут, а не где-нибудь ещё? Сейчас объясню.

В initState() контекст твоего виджета может быть ещё сырой, недопечённый, как будто на дворе 2002-й год и интернет только подключается. Он может просто не найти этот самый InheritedWidget в дереве, и будет тебе null вместо данных — волнение ебать, а потом и ошибка. А didChangeDependencies() — он как раз гарантирует, что контекст уже готов, причёсан и может спокойно найти все зависимости. Доверия к нему — не ноль, а вполне себе овердохуища.

Ну а если делать подписку прямо в build()? Технически-то можно, ядрёна вошь, никто не запретит. Но это пиздопроебибна идея, потому что build() вызывается чаще, чем ты моргаешь. Каждый чих, каждый писк — и он уже тут как тут. Получится, что ты будешь подписываться и отписываться, как мартышлюшка на банановой плантации, и производительность твоего приложения накроется медным тазом. Зачем тебе этот геморрой?

Короче, запомни раз и навсегда: didChangeDependencies() — твой друг, товарищ и брат. Туда и клади свою подписку, и будет тебе счастье, а не хиросима.