【问题标题】:Does StatefulWidget not rebuild State every time it has new data?StatefulWidget 每次有新数据时都不会重建 State 吗?
【发布时间】:2022-04-28 00:49:00
【问题描述】:

当点击相应的菜单按钮时,小部件 TrainsPage 将添加到 main.dart 中的构建图。这会执行两次:一次是在 _routes 为空时,第二次是在 _routes 被填充时。

Widget pageSelector() {
   if (_selectedIndex == 2) {
      return new TrainsPage(routes: _routes);
    } else
      return Text("");
  }

在 TrainsPage.dart 中,我有状态小部件 TrainsPage 的代码。

class TrainsPage extends StatefulWidget {
  const TrainsPage({Key? key, required this.routes}) : super(key: key);

  final List<RSRoute> routes;

  @override
  _TrainsPageState createState() => _TrainsPageState();
}

class _TrainsPageState extends State<TrainsPage> {
  List<RSRoute> _routes = List.empty();

  @override
  void initState() {
    super.initState();
    this._routes = new List<RSRoute>.from(widget.routes);

现在,第二次,在 main.dart 中调用 TrainsPage(现在填充了 routes),_TrainsPageStateinitState() 是未调用,它负责读取 routes 中的数据。由于 routes 第一次是空的,所以火车页面上没有显示任何内容。

为什么TrainsPage不重建_TrainsPageState,当它在构造函数中明确获得新数据时?

【问题讨论】:

  • init state 将在一种情况下被调用,如果它的参数已经改变,或者它假设在这个 Widget 中没有什么要更新的
  • @nitishk72 有没有办法强制 TrainsPage 重建 _TrainsPageState?我猜想在 Jetpack Compose 中将更改委托给小部件树的原则会起作用。在 Flutter 中是不是很相似?
  • 只需将此key: UniqueKey() 添加到您的小部件TrainsPage(key: UniqueKey(), routes: routes)

标签: flutter


【解决方案1】:

这正是 State 存在的原因:即使在重新构建小部件时也能保持当前上下文的状态。

如果每次重建有状态小部件时都重新创建它,则它无法保持其自身变量的状态。

class MyWidget extends StatelessWidget {
  var _someStateVariable = 0;

  @override
  void build(BuildContext context){
    // here an action that increment _someStateVariable
  }

}

这里 _someStateVariable 将在每次重建时重置为 0。或者,如果我们首先想要一个 StateFullWidget,那是因为我们稍后会更新这个变量,并希望通过多个小部件重建来保持其更新的值。 如果你没有这样的状态变量来维护,也许你在这里不需要 StateFullWidget。

现在解决您的问题:您可以覆盖 didUpdateWidget 而不是 initstate,因为它将在每次小部件重建时调用:

@override
  void didUpdateWidget() {
    didUpdateWidget();
   _routes = new List<RSRoute>.from(widget.routes);
}

【讨论】:

  • 谢谢,这很有帮助。为了完整起见,我最终将初始化代码放入了它自己的函数中,该函数从 initState 和 didUpdateWidget 调用。 @override void didUpdateWidget(TrainsPage oldWidget) { super.didUpdateWidget(oldWidget); setState(() { 初始化(); }); }
  • 不客气。有关信息,因为每次调用 didUpdateWidget 时都会重新构建小部件,因此在其中调用 setState 是不必要且多余的。
  • 这个概念,即状态被记住,即使覆盖的 Widget 是重建的,真的很有趣。我们可以从上面添加日期,同时保持下面的用户状态。我想,这是通过 Jetpack compose 中的“remember”关键字完成的。 stackoverflow.com/questions/65368007/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2011-03-22
  • 2022-07-27
  • 2016-07-07
  • 2021-10-14
相关资源
最近更新 更多