Каждый раз, когда я ухожу от виджета, а затем возвращаюсь к нему, я получаю вызов "n+1" метода initState этого виджета.
У меня установка примерно такая. Я начинаю с виджета A, когда распознан щелчок по карте, мы делаем Navigator.pushNamed(B.routeName), чтобы отобразить экран подробностей для этого элемента. После выполнения дополнительной обработки пользователь нажимает кнопку «Отправить» на B и возвращается к a с помощью Navigator.pushNamed(A.routeName).
class A extends StatefulWidget {
static String routeName = 'aroutename';
A({Key key}) : super(key: key);
_AState createState() => _AState();
}
class _AState extends State<A> {
@override
void initState() {
super.initState();
getSomeDataForScreenA().then((result) => setState(...));
}
whenDone(){
Navigator.of(context).pushNamed(B.routeName);
}
@override
Widget build(BuildContext context) {
return Container(
);
}
}
class B extends StatefulWidget {
B({Key key}) : super(key: key);
_BState createState() => _BState();
}
class _BState extends State<B> {
static String routeName = 'broutename';
@override
void initState() {
super.initState();
getSomeDataForScreenB().then((result) => setState(...));
}
whenDone(){
Navigator.of(context).pushNamed(A.routeName);
}
@override
Widget build(BuildContext context) {
return Container(
);
}
}
В первый раз, когда мы видим A, все в порядке, он запускается только один раз. Затем мы идем к B, а затем, как только мы возвращаемся к A, initState() вызывается дважды. В третий раз делаем этот цикл, он вызывается 3 раза и т.д...
Надеюсь, кто-то может указать мне в правильном направлении, что я делаю неправильно. Я знаю, что это, вероятно, связано с непониманием внутренней работы Navigator.of(context), но я нигде не могу найти ответ.
Navigator работает как стек. Он используется для нажатия и выталкивания «маршрута». Виден самый верхний маршрут.
Вот что вы делаете:
Я предполагаю, что поскольку routeName для всех As и B в стеке одинаково, состояние восстанавливается.
Что вы должны сделать, это: Нажмите B, когда закончите, вместо этого снова нажмите A.
whenDone должно выглядеть так:
whenDone(){
Navigator.of(context).pop();
}
Дайте мне знать, если это решит вашу проблему. Если нет, то дайте мне знать, какая у вас проблема с этим.
Так что я мог бы это сделать, но причина, по которой я выбрал маршрут «push», заключалась в том, что я хотел, чтобы состояние инициализации запускалось снова (не дважды, а только один раз при повторной инициализации), чтобы приложение могло получить самую последнюю версию вещи, которые потенциально были обновлены на Экране B.
Я понимаю, что это немного расточительно с точки зрения сетевых запросов, но это значительно упрощает логику обеспечения соответствия локального состояния вещей состоянию вещей на стороне сервера.
В настоящее время я использую шаг VSCode через отладчик, чтобы попытаться определить, почему происходит (n + 1) initState. Я буду обновлять эту тему, если смогу ее найти.
дайте 'key: UniqueKey' каждому нажатому маршруту, это может решить. это некоторая проблема дублирования состояния.
если вы посмотрите на мое объяснение выше, вы увидите, что это исправило. Я не уверен, что это ясно. Вы знакомы с плагином flutter_redux?
понятия не имею о редуксе
Что бы вы сделали, если бы прошли более одного маршрута, например [A, B, C, [D], A]? Использовать popUntil?
@KeithDC popUntil - это то, что я делаю
Итак, похоже, проблема была в том, как я использовал плагин flutter_redux. Не совсем уверен, что вызвало это, но я полагаю, что это просто принудительное отображение повторяющегося состояния из-за того, как я его использовал.
Короче говоря, я хранил active_tab для BottomTab в состоянии редукции, а не в локальном состоянии для контейнера экрана Home, который у меня был. Причина, по которой я сделал это в первую очередь, заключалась в том, чтобы я мог протолкнуть маршрут на дом, а затем также манипулировать вкладкой, которую он собирался сделать активной в первую очередь.
Я думаю, что просто проведу рефакторинг и использую здесь что-то вроде Флюро, чтобы позволить мне передавать аргументы моим маршрутам, чтобы я мог отображать конкретную вкладку.
Надеюсь, если кто-то еще столкнется с этой проблемой, это поможет, заранее извиняюсь за то, что не обязательно нашел основную причину, по которой он выполнял повторный рендеринг.
Когда закончите, почему бы просто не использовать Navigator pop?