Мне интересно, каков рекомендуемый способ передачи данных в виджет с отслеживанием состояния при его создании.
Я видел два стиля:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState(_server);
}
class _ServerInfoState extends State<ServerInfo> {
Server _server;
_ServerInfoState(Server server) {
this._server = server;
}
}
Этот метод сохраняет значение как в ServerInfo
и _ServerInfoState
, что кажется немного расточительным.
Другой метод - использовать widget._server
:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState();
}
class _ServerInfoState extends State<ServerInfo> {
@override
Widget build(BuildContext context) {
widget._server = "10"; // Do something we the server value
return null;
}
}
Это кажется немного отсталым, поскольку состояние больше не сохраняется, _ServerInfoSate
а хранится в виджете.
Есть ли лучший способ для этого?
ServerInfo(this._server);
Ответы:
Не передавайте параметры
State
его конструктору. Доступ к ним можно получить только с помощьюthis.widget.myField
.Не только редактирование конструктора требует большого количества ручной работы; это ничего не приносит. Нет причин дублировать все поля
Widget
.РЕДАКТИРОВАТЬ :
Вот пример:
источник
State
уже как доступ ко всем свойствамStateful
с помощьюwidget
поля.void initState()
состояние, чтобы установить начальное значение. Отметьте этот вариант резьбы C в качестве примера.Лучший способ - не передавать параметры классу State с помощью его конструктора. Вы можете легко получить доступ к классу State, используя
widget.myField
.Например
Передайте свои данные при навигации по экрану:
источник
Другой ответ, основанный на anwser @RémiRousselet и вопросе @ user6638204, если вы хотите передать начальные значения и все же иметь возможность обновлять их в состоянии позже:
источник
MyStateful
имеет один необязательный именованный параметр (свойство), вы можете создать этот виджет, позвонивMyStateful(foo: "my string",)
initState
не решает проблему в следующем сценарии: например, вы создали виджет Statefull с пустыми параметрами и ждете загрузки данных. Когда данные загружены, вы хотите обновить виджет Statefull свежими данными, и в этом случае, когда вы вызываете MyStatefull (newData), онinitState()
не будет вызываться! В этом случаеdidUpdateWidget(MyStatefull oldWidget)
будет называться , и вам нужно будет сравнить данные из аргументовoldWidget.getData()
с ,widget.data
и если это не то же самое - вызовsetState()
для восстановления виджета.Для передачи начальных значений (ничего не передавая конструктору)
источник