为什么 setState 需要关闭?
Why does setState take a closure?
让 setState()
接受一个函数只是立即调用它然后请求重建有什么好处?特别是,与让用户显式调用 "rebuild" 类型的函数相比有什么优势?
当 Flutter 有一个“markNeedsBuild”函数时,开发人员最终只是随机调用它。当语法切换为 setState(() { ... })
时,开发人员更有可能正确使用 API。从机器的角度来看,它们在功能上是等同的,但它们似乎唤起了开发人员的不同代码。
如果您遵循仅在 setState
闭包内改变成员变量的惯例,您将避免在重构某些代码时意外删除对 setState
的调用或调用setState
不必要。如果你的 State
被卸载,Flutter 可能会失败断言,所以你一开始尝试改变成员就知道出了什么问题,而不是在最后。
最终可能会有一个 analyzer warning enforcing that setState
is always called when mutating members of a State
,因此在 initState
或 setState
回调之外发生的任何成员变量突变都将被标记为可疑。
如果您刚刚开始使用 Flutter 中的状态,请查看 Flutter widgets tour. I've found that a lot of cases where I was calling setState
can be handled more elegantly with FutureBuilder
, StreamBuilder
, AnimatedWidget
, or AnimatedBuilder
,所以如果您发现自己经常调用 setState
,请不要忘记考虑这些替代方案。
Adam Barth 和 Yaroslav Volovich 对此做出了贡献 question/answer。
为了完成 Colin 的回答,它还确保您在处理异步函数时在正确的时刻调用 setState
。
在回调之外改变你的状态可能会导致一个简单的错误:
function() async {
setState(() {});
myState = await future;
}
这会导致问题,因为如果您的未来未同步完成,将在状态发生变化之前调用构建方法。
通过使用回调,您必须执行以下操作:
function() async {
final value = await future;
setState(() {
myState = value;
});
}
这一次,它不会引起问题,因为在 setState 之前等待未来。
我不能进行异步回调但问题仍然存在吗?
没有。因为 setState 方法在内部检查回调不 return 未来。如果是,它将抛出。
所以以下是不可能的:
setState(() async {
myState = await future;
});
让 setState()
接受一个函数只是立即调用它然后请求重建有什么好处?特别是,与让用户显式调用 "rebuild" 类型的函数相比有什么优势?
当 Flutter 有一个“markNeedsBuild”函数时,开发人员最终只是随机调用它。当语法切换为 setState(() { ... })
时,开发人员更有可能正确使用 API。从机器的角度来看,它们在功能上是等同的,但它们似乎唤起了开发人员的不同代码。
如果您遵循仅在 setState
闭包内改变成员变量的惯例,您将避免在重构某些代码时意外删除对 setState
的调用或调用setState
不必要。如果你的 State
被卸载,Flutter 可能会失败断言,所以你一开始尝试改变成员就知道出了什么问题,而不是在最后。
最终可能会有一个 analyzer warning enforcing that setState
is always called when mutating members of a State
,因此在 initState
或 setState
回调之外发生的任何成员变量突变都将被标记为可疑。
如果您刚刚开始使用 Flutter 中的状态,请查看 Flutter widgets tour. I've found that a lot of cases where I was calling setState
can be handled more elegantly with FutureBuilder
, StreamBuilder
, AnimatedWidget
, or AnimatedBuilder
,所以如果您发现自己经常调用 setState
,请不要忘记考虑这些替代方案。
Adam Barth 和 Yaroslav Volovich 对此做出了贡献 question/answer。
为了完成 Colin 的回答,它还确保您在处理异步函数时在正确的时刻调用 setState
。
在回调之外改变你的状态可能会导致一个简单的错误:
function() async {
setState(() {});
myState = await future;
}
这会导致问题,因为如果您的未来未同步完成,将在状态发生变化之前调用构建方法。
通过使用回调,您必须执行以下操作:
function() async {
final value = await future;
setState(() {
myState = value;
});
}
这一次,它不会引起问题,因为在 setState 之前等待未来。
我不能进行异步回调但问题仍然存在吗?
没有。因为 setState 方法在内部检查回调不 return 未来。如果是,它将抛出。
所以以下是不可能的:
setState(() async {
myState = await future;
});