我是 flutter 的新手,真的想知道当我们调用 setState 时是否所有小部件的子树都得到重建。
这里的子树是指该小部件下面的所有小部件树(包括该小部件作为根节点)。
当我们调用setState函数时,会在子树的build上调用该方法root node,从而触发其子树上的构建方法。假设MyWidget1子树(该小部件的子节点)的分支(此处)与状态变量无关。我注意到即使是独立的分支也会setState在父节点调用时重建。
class _MyAppState extends State<MyApp> {
int count=0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: <Widget>[ MyWidget1(),MyWidget2(count),],),
floatingActionButton: FloatingActionButton(onPressed: ()=>setState((){count++;}),),
);
}
}
class MyWidget1 extends StatelessWidget {
@override
Widget build(BuildContext context) { print("widget builds 1");
return Container(height: 100, color: Colors.orange,);
}
}
class MyWidget2 extends StatelessWidget {
final int count;
MyWidget2(this.count);
@override
Widget build(BuildContext context) { print("widget builds 2");
return Text(count.toString());
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我们可以看到,MyWidget1状态变量是独立的(这里count),所以一般来说,setState应该对它没有影响。我想知道是否应该进行任何优化来避免MyWidget1在setState函数调用时进行无用的构建。由于下面的树MyWidget1可能太大,那也将再次重建。
我的问题:
这个独立小部件(这里MyWidget1)可以再次构建setState吗?
有没有更好的方法来处理这种情况以避免其重建。
注意:我已经阅读了这个问题
在这个问题中,有一种方法可以通过在构建方法之外创建独立分支的实例来避免无用的构建,
我的疑问是:
这是处理这种情况的方法还是其他更好的方法,或者这种情况根本没有那么大,因为树在 O(n) 时间内构建(我认为这不应该是答案,因为构建树可能是 O( n) 操作,但它可能包括许多耗时的操作,这些操作可能对一次又一次无用地调用可能不是优化友好的)。
是的,MyWidget1是在此基础上重建的setState。只相信代码。在您调用 之后setState,build被调用,它调用 的构造函数MyWidget1。在每个 之后setState,整个子树被重建。旧的小部件被扔掉。然而,国家并没有被抛弃。状态实例会继续存在,不会重新创建(请参阅 didUpdateWidget)。
所以,是的。在每个 之后setState,整个子树被重建。
这没关系,别担心。
这里的小部件类是非常轻量级的类。Dart 的垃圾收集器经过优化,可以实例化许多此类对象并将它们一起丢弃。
您可以一次又一次地重新创建的这棵树只是一个外观。还有两个并行的树不是轻量级的,也没有重新创建。您的小部件树被区分在一起,以找出系统应如何修改实际的 ui 元素。
你可能会问,为什么会有这么多麻烦。因为创建树很容易,维护它们很困难。这种反应式声明式框架让我们可以只创建树而不维护它。
有一些关于 Flutter 内部的资源,您可以阅读更多相关内容。一个这样的资源是这个视频:https : //www.youtube.com/watch?v=996ZgFRENMs