Сами экземпляры StatefulWidget являются неизменяемыми и хранят свое изменяемое состояние либо в отдельных объектах State, созданных методом createState, либо в объектах, к которым подписывается это State, напримерОбъекты Stream или ChangeNotifier, ссылки на которые хранятся в конечных полях самого StatefulWidget.
Фреймворк вызывает createState всякий раз, когда он раздувает StatefulWidget, что означает, что несколько объектов State могут быть связаны с одним и тем же StatefulWidget, если этот виджетбыл вставлен в дерево в нескольких местах.Точно так же, если StatefulWidget удаляется из дерева, а затем снова вставляется в дерево, платформа снова вызовет createState для создания нового объекта State, упрощая жизненный цикл объектов State.
StatefulWidget сохраняет то же самоеСостояние объекта при перемещении из одного места в дереве в другое, если его создатель использовал GlobalKey для своего ключа.Поскольку виджет с GlobalKey может использоваться не более чем в одном месте дерева, у виджета, использующего GlobalKey, может быть не более одного связанного элемента.Каркас использует это свойство при перемещении виджета с глобальным ключом из одного места в дереве в другое, прививая (уникальное) поддерево, связанное с этим виджетом, из старого местоположения в новое местоположение (вместо воссоздания поддерева вНовое место).Объекты State, связанные с StatefulWidget, создаются вместе с остальной частью поддерева, что означает, что объект State повторно используется (а не создается заново) в новом местоположении.Однако, чтобы иметь право на прививку, виджет должен быть вставлен в новое местоположение в том же кадре анимации, в котором он был удален из старого местоположения.
Соображения производительности
Естьдве основные категории StatefulWidgets.
Первая - это та, которая выделяет ресурсы в State.initState и удаляет их в State.dispose, но которая не зависит от InheritedWidgets или вызова State.setState.Такие виджеты обычно используются в корне приложения или страницы и взаимодействуют с подвиджетами через ChangeNotifiers, Streams или другие подобные объекты.Виджеты с отслеживанием состояния по такому шаблону относительно дешевы (с точки зрения циклов процессора и графического процессора), поскольку они создаются один раз, а затем никогда не обновляются.Поэтому они могут иметь несколько сложные и глубокие методы сборки.
Вторая категория - это виджеты, которые используют State.setState или зависят от InheritedWidgets.Обычно они перестраиваются много раз за время существования приложения, поэтому важно минимизировать влияние перестройки такого виджета.(Они могут также использовать State.initState или State.didChangeDependencies и распределять ресурсы, но важной частью является то, что они перестраиваются.)
«Объекты флаттера» довольно широки.Существуют разные виды объектов.
Состояние и виджет разделены и имеют разные жизненные циклы.Неизменность используется по соображениям производительности.Если виджет должен измениться, создайте новый экземпляр, настроенный соответствующим образом.Быстрее проверить, идентичны ли два экземпляра, чем если бы их состояние было одинаковым.