我有一个父子状态小部件。通常,当父级重建时,我希望它重用现有的子状态并调用 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)没有移动
最佳答案
好的,这是我认为 发生的事情 - 如果我错了请纠正我。 答案在我附加的小部件树中。 如您所见,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/