Опыт Flutter — управление состоянием виджета

внешний интерфейс React.js Flutter React Native
Опыт Flutter — управление состоянием виджета

Идея дизайна Flutter состоит в том, чтобы отделить представления от данных, как в React. В приложении Flutter, когда фреймворку необходимо повторно отобразить представление, он вызывает метод сборки грязного виджета, который использует внешние данные и состояние для построения.Widget Tree, что, в свою очередь, заставляет фреймворк строиться внутриRender Tree. Последнее нам в принципе не нужно трогать в ежедневной разработке, поэтому основная работа заключается в построении логики Дерева виджетов.

Виджеты Flutter делятся на два типа, один из нихStatelessWidget, другойStatefulWidget, первое обычно используется для отображения статического контента, а второе — для интерактивного и логического контента.

В этой статье мы в основном обсуждаем StatefulWidget.

Сначала посмотрите на пример:

@override
Widget build(BuildContext context) {
  var contents = <Widget>[
    new RaisedButton(
      child: const Text('Change Color'),
      onPressed: () { _invertColorFlag(); },
    ),
    const SizedBox(height: 10.0),
    new RaisedButton(
      child: const Text('Change Position'),
      onPressed: () { _invertPositionFlag(); },
    ),
  ];

  final statefulWidget = new _MyStatefulWidget(
    value: 10,
    textColor: _colorFlag ? const Color(0xffff0000) : null,
  );

  if (_positionFlag) {
    contents.add(statefulWidget);
  } else {
    contents.insert(0, statefulWidget);
  }

  return new Scaffold(
    appBar: new AppBar(
      title: const Text('Stateful Demo'),
    ),
    body: new Center(
      child: new Column(
        mainAxisSize: MainAxisSize.min,
        children: contents,
      ),
    ),
  );
}

_MyStatefulWidget — это настраиваемый виджет, который представляет собой простой счетчик, и мы можем изменить его начальное значение и стиль с помощью параметров:

Эффект запуска примерного приложения выглядит следующим образом (загруженные изображения Zhihu слишком бесполезны и сообщают непосредственно о превышении лимита памяти, вот статическое изображение):

Но проблема возникает, когда мы нажимаем кнопку «Изменить позицию»:

Состояние счетчика сбрасывается.Почему так происходит?Начнем с того,как работает Flutter.

когда мы проходимsetStateКогда метод изменяет состояние виджета, Flutter повторно вызывает метод сборки соответствующего состояния для восстановления дерева виджетов.После того, как Flutter получит последнее дерево виджетов, он сравнит его с текущим деревом виджетов.Он очень похож к идее ВДом? Когда каждый виджет находится в одной и той же позиции в дереве (изменяются только свойства виджета), Flutter распознает его и повторно использует предыдущий объект состояния, поэтому состояние этого виджета будет сохранено.

Однако, когда мы нажимаем кнопку «Изменить позицию», мы меняем положение счетчика в дереве виджетов, из-за чего внутреннее дерево не может определить, является ли новый счетчик исходным, поэтому Flutter решает не использовать его повторно. и воссоздать новое состояние через createState.

На самом деле решение очень простое: студенты, которые использовали React, уже знают ответ: использовать ключ.

Виджет можно однозначно идентифицировать по ключу. Ключ особенно важен в представлении списка, поскольку он позволяет более эффективно вычислять, какие элементы были добавлены, а какие были удалены или заменены местами. То же самое верно и для Flutter. Создание ключа во Flutter так же просто, как одна строка:

final _statefulKey = new GlobalKey(debugLabel: '_MyStatefulWidget');

Этот ключ особенный, потому что он уникален во всем приложении, и Flutter отвечает за его создание и обеспечение его уникальности. Этот тип ключа более применим в нашем примере, но не так применим в представлении списка.Мы хотим, чтобы представление соответствовало данным один за другим.В этом случае нам нужноValueKey.

Комбинированный режим

Flutter официально выступает за использование шаблона под названием «смешивание и сопоставление» для разработки виджетов с отслеживанием состояния, который также очень похож на React.Lifting State UpЛучшие практики. Проще говоря, это не позволяет классу ввода Widget (например, Slider, Checkbox и т. д., включая наш счетчик выше) управлять им самостоятельно.«Статус данных», так называемое состояние данных Основные данные, отображаемые виджетом, например ползунком, в основном предназначены для графического представления доли. Это значение доли должно управляться родительским представлением. Самому ползунку нужно только управлять некоторой анимацией и визуальными состояниями.


References:

[1] Adding Interactivity to Your Flutter App

[2] StatefulWidget class

[3] Flutter for React Native Developers