flutter - 在父 setState 之后子状态对象被替换(initState)而不是更新(didUpdateWidget)

标签 flutter dart

我有一个父子状态小部件。通常,当父级重建时,我希望它重用现有的子状态并调用 didUpdateWidget。

然而,在我的例子中,它并没有这样做;相反,它会创建一个全新的状态对象并对其调用 initState,从而丢失我之前的所有状态信息。

医生是这么说的

By default, the framework matches widgets in the current and previous build according 
to their runtimeType and the order in which they appear.

首先,“顺序”在这种情况下是什么意思?我假设这意味着小部件树中的位置,对吗? 其次,由于我的 Widget 树没有改变,我希望 flutter 重用旧状态而不是创建新状态。 我不确定如何调试它。如何检查新旧小部件的“顺序”以查看它们是否不同?

我的代码库相当大,所以我会尽量只包含相关部分:

class Parent extends StatefulWidget {
  @override
  _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  String _remaining;

  void updateRemaining(String remaining) {
    setState(() => _remaining = remaining);
  }

  Widget build(BuildContext context) {
    //somewhere
    return Child(updateRemaining:updateRemaining);
  }
}

class Child extends StatefulWidget {
  final Function updateRemaining;
  Child({this.updateRemaining});

  @override
  _ChildState createState() => new _ChildState();
}

class _ChildState extends State<Child> {

//somewhere:
widget.updateRemaining("0");
}

在最后一次调用之后:widget.updateRemaining("0"); flutter 处理子状态并创建一个新的而不是重用旧的。

我使用 Flutter inspector 查看了 widgets 树,看起来 Homepage(=child widget)相对于 MainApp(=parent widget)没有移动

在 widget.updateRemaining("0") 之前;打电话 before widget.updateRemaining("0"); call

在 widget.updateRemaining("0") 之后;打电话 after widget.updateRemaining("0"); call

最佳答案

好的,这是我认为 发生的事情 - 如果我错了请纠正我。 答案在我附加的小部件树中。 如您所见,Scaffold 有一个 GlobalKey,它会发生变化并因此强制重建,因为根据文档:

Use keys to control which widgets the framework matches up with other widgets when a widget rebuilds. By default, the framework matches widgets in the current and previous build according to their runtimeType and the order in which they appear. With keys, the framework requires that the two widgets have the same key as well as the same runtimeType.

由于键不同,Scaffold 状态对象被处置包括它的所有子部件,并创建一个新的。 显然,创建一个新的状态对象会强制重新创建整个子树,无论它是否与旧的相同。

关于flutter - 在父 setState 之后子状态对象被替换(initState)而不是更新(didUpdateWidget),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56978229/

相关文章:

flutter - Dart 代码片段不与 Sentry 仪表板上的堆栈跟踪一起显示

flutter - 如何将 Future<StreamedResponse> 转换为 Future<Response>?

Flutter - 添加边框时半径边框消失

flutter - 如何在启用阴影的情况下运行 Flutter 小部件测试?

dart - 在组件之间共享变量

dart - 如何在 Dart 中使对象成为一次性对象?

dart - 如何将多个数据流合并到一个 BLOC 中?

flutter - 如何在 flutter 中创建像这样的图像的列表按钮

dart - Flutter:是否有可能创建 App Widgets (Android) 和 Today Extensions (iOS)?

firebase - 有没有一种简单的方法可以找到在 flutter 中使用权限的包? Info.plist 提交问题中缺少目的字符串