Flutter 整个子树是否在颤振状态下重建
我是一个新手,我真的很想知道当我们调用setState时,是否所有小部件的子树都得到了重建 这里的子树是指该小部件下面的所有小部件树(包括作为根节点的小部件) 当我们调用Flutter 整个子树是否在颤振状态下重建,flutter,Flutter,我是一个新手,我真的很想知道当我们调用setState时,是否所有小部件的子树都得到了重建 这里的子树是指该小部件下面的所有小部件树(包括作为根节点的小部件) 当我们调用setState函数时,子树的根节点上调用build方法,从而触发其子节点上的build方法。假设子树(该小部件的子级)的分支(此处MyWidget1)独立于状态变量。我注意到,甚至独立的分支都是在父节点中调用的setState上重建的 class _MyAppState extends State<MyApp> {
setState
函数时,子树的根节点上调用build
方法,从而触发其子节点上的build方法。假设子树(该小部件的子级)的分支(此处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());
}
}
class\u MyAppState扩展状态{
整数计数=0;
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:列(子项:[MyWidget1(),MyWidget2(计数),],),
floatingActionButton:floatingActionButton(按下时:()=>setState((){count++;})),
);
}
}
类MyWidget1扩展了无状态小部件{
@凌驾
小部件构建(BuildContext上下文){print(“小部件构建1”);
返回容器(高度:100,颜色:Colors.orange,);
}
}
类MyWidget2扩展了无状态小部件{
最终整数计数;
MyWidget2(this.count);
@凌驾
小部件构建(BuildContext上下文){print(“小部件构建2”);
返回文本(count.toString());
}
}
这里我们可以看到,MyWidget1
独立于状态变量(这里是count
),因此通常,setState
应该不会对其产生影响。
我想知道是否应该进行任何优化,以避免调用setState
函数时生成无用的MyWidget1
。由于MyWidget1下方的树可能太大,因此将再次重建该树
我的问题是:
这个独立小部件(此处MyWidget1
)可以在setState
上重新构建吗
有没有更好的方法来处理这种情况,以避免其重建
注:我已经读过了
在这个问题中,有一种方法可以通过在build方法之外创建独立分支的实例来避免无用的build
我的疑问是:
这是处理这种情况的方法还是其他更好的方法,或者这种情况根本没有那么大,因为树是在O(n)时间内构建的(我认为这不应该是答案,因为构建树可能是O(n)操作,但它可能包含许多耗时的操作,这些操作可能不利于优化,无法重复调用)。只要相信代码。调用setState
后,将调用build
,它调用MyWidget1
的构造函数。在每次设置state
之后,将重建整个子树。旧的小部件被扔掉了。然而,国家并没有被抛弃。状态实例存在于上,不会重新创建它们(请参见didUpdateWidget)
所以,是的。在每次设置state
之后,将重建整个子树
没关系,别担心
这里的小部件类是非常轻量级的类。Dart的垃圾收集器经过优化,可以实例化许多这样的对象并将它们一起丢弃
你一次又一次地重建的这棵树只是一个门面。还有两个并行树不是轻量级的,也不会重新创建。您的小部件树被区分在一起,以发现系统应该如何修改实际的ui元素
你可能会问,为什么要这么麻烦。因为创建树很容易,维护树很困难。这种反应式声明性框架让我们只需创建树,而不需要维护它
有一些关于颤振内部的资源,您可以阅读更多关于这方面的内容。一个这样的资源就是这个视频:class\u MyAppState扩展状态{
整数计数=0;
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:列(子项:[const MyWidget1(),MyWidget2(计数),],),
floatingActionButton:floatingActionButton(按下时:()=>setState((){count++;})),
);
}
}
类MyWidget1扩展了无状态小部件{
常量MyWidget1();
@凌驾
小部件构建(BuildContext上下文){print(“小部件构建1”);
返回容器(高度:100,颜色:Colors.orange,);
}
}
类MyWidget2扩展了无状态小部件{
最终整数计数;
MyWidget2(this.count);
@凌驾
小部件构建(BuildContext上下文){print(“小部件构建2”);
返回文本(count.toString());
}
}
当构造函数以“const”关键字开始时,允许
您需要缓存和重用小部件
调用构造函数来启动小部件时,请使用“const”关键字。通过使用“const”关键字调用,小部件不会在其他小部件更改时重建
他们的状态在树上。如果省略了“const”关键字,则每次调用父级时都会调用该小部件
小部件重画
class _MyAppState extends State<MyApp> {
int count=0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: <Widget>[ const MyWidget1(),MyWidget2(count),],),
floatingActionButton: FloatingActionButton(onPressed: ()=>setState((){count++;}),),
);
}
}
class MyWidget1 extends StatelessWidget {
const MyWidget1();
@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());
}
}