StatelessWidget
的所有代码都在一个类中,甚至是build
方法。对于StatefulWidget
,为什么State
与Widget
分开?他们不能合并,StatefulWidget
可以自己调用setState
吗?
答案 0 :(得分:4)
StatefulWidget
类是不可变的,并将其构造函数参数存储在final
成员中。当配置信息更改并替换为新的StatefulWidget
时,它将被丢弃。此操作通常非常便宜,并触发重建。
相比之下,State
的相关StatefulWidget
可以是长寿的。只要树结构和键匹配,即使构造函数参数发生更改,在替换State
时也会重用StatefulWidget
。这样即使父母改变了State
的内容,也可以让StatefulWidget
不被吹走。例如,您可能希望在动画中间更改窗口小部件的颜色或文本,State
会注意到,因为它使用widget
getter来读取这些值。 (这就是State
必须永远不能有任何构造函数参数的原因;它必须使用widget
来读取其配置。)
如果您希望为重新配置StatefulWidget
的情况提供特殊处理,可以通知您didUpdateWidget
中发生了哪些更改,但通常只是重建会产生预期结果。
答案 1 :(得分:0)
也许这有助于你: Design discussion
在State上放置Widget构建(BuildContext context)方法,而不是在StatefulWidget上放置Widget构建(BuildContext上下文,State状态)方法,为子类化StatefulWidget时开发人员提供了更大的灵活性。
例如,AnimatedWidget是StatefulWidget的子类,它为其子类引入了一个抽象的Widget构建(BuildContext context)方法来实现。如果StatefulWidget已经有一个带有State参数的构建方法,AnimatedWidget将被强制将其State对象提供给子类,即使它的State对象是AnimatedWidget的内部实现细节。
从概念上讲,StatelessWidget也可以以类似的方式实现为StatefulWidget的子类。如果构建方法是在StatefulWidget而不是State上,那就不可能了。
将构建函数放在State而不是StatefulWidget上也有助于避免与隐式捕获它的闭包相关的一类错误。如果您在StatefulWidget上的构建函数中定义了一个闭包,那么该闭包将隐式捕获它,这是当前的窗口小部件实例