Какого черта setState () иногда не работает?
Как заставить виджет перерисовываться во Flutter?
… И почему Flutter пытается переработать состояние виджетов?
Сколько раз вы вызывали setState (), но на экране ничего не менялось, хотя внутреннее состояние виджета изменилось?
Я знаю, что много раз :)
Итак, простой экран с текстом, который отображает текущее значение, которое увеличивается каждый раз, когда пользователь нажимает кнопку. Это было бы несложно, если бы мы использовали текстовый виджет без сохранения состояния - ›он будет перестраиваться каждый раз, когда пользователь нажимает кнопку.
Но наша реализация текста выглядит так:
Мы берем начальное значение из виджета и сохраняем его локально в объекте State во время выполнения initState (). initState () вызывается только в первый раз, когда пользователь нажимает кнопку, и никогда больше, поэтому мы не видим изменений на экране. Но почему это происходит?
На самом деле Flutter работает именно так: пытается сохранить состояние виджета с отслеживанием состояния.
Виджеты неизменяемы, что означает, что их необходимо перестраивать для каждого setState (), но их состояние сохраняется до тех пор, пока в той же позиции в дереве (дереве элементов) не появится новый виджет с другой ТИП или другой КЛЮЧ!
В нашем примере наш виджет находится в том же месте, что и раньше (тот же виджет, поэтому, конечно, того же типа), и мы не использовали ключи, поэтому с точки дерева элементов , ничего не изменилось, и состояние сохраняется.
Мы не хотим менять тип нашего виджета, но можем ввести ключи! :)
При добавлении UniqueKey во время setState () корневого виджета состояние MyStatefulText будет восстановлено с нуля, а его initState () будет вызываться каждый раз, когда пользователь нажимает кнопку.
Ура, работает! :)
Но в большинстве случаев вы не хотите, чтобы ваш виджет перерисовывался каждый раз, когда родительский элемент выполняет setState (), что вы будете делать с помощью UniqueKey , из нашего примера.
Если вы хотите выполнять перерисовку только в особых случаях, вы можете использовать ValueKey. Установив этот тип ключа, ваша перерисовка будет выполняться, только если значение этого ключа изменится.
redrawObject is a property inside _MyStatefullTextState class!
По сути, мы при каждом втором нажатии перерисовываем MyStatefulText. А сейчас это выглядит так:
Заинтересованы в присоединении к Medium по моей реферальной ссылке? 💙
Спасибо! :)
… И если вам понравилась эта статья, пожалуйста, несколько раз хлопните в ладоши :)