让setState()
接受函数只是为了立即调用它然后请求重建的好处是什么?特别是,使用户明确地调用"重建"的优点是什么?类型功能?
答案 0 :(得分:18)
当Flutter有一个" markNeedsBuild"功能,开发人员最终只是随机调用它。当语法切换到setState(() { ... })
时,开发人员更有可能正确使用API。功能上从机器的角度来看是相同的,但它们似乎从开发人员那里唤起了不同的代码。
如果您遵循仅在setState
关闭内变更成员变量的惯例,那么您将避免重构某些代码并意外删除对setState
的调用的情况,或者不必要地致电setState
。如果您的State
已卸载,Flutter可能会失败一个断言,因此一旦您开始尝试改变成员而不是最终,您就会知道出现问题。
最终可能会analyzer warning强制执行setState
在变更State
的成员时始终被调用,因此任何成员变量突变发生在initState
之外或setState
回调将被标记为可疑。
如果您刚开始使用Flutter中的州,请查看Flutter widgets tour。我发现使用FutureBuilder
,StreamBuilder
,AnimatedWidget
或AnimatedBuilder
可以更优雅地处理我呼叫setState
的许多案例,如果你发现自己经常打setState
,请不要忘记考虑这些替代方案。
Adam Barth和Yaroslav Volovich对这个问题/答案做出了贡献。
答案 1 :(得分:3)
柯林·杰克逊的答案是正确的。
但这不是唯一的原因。它还可以确保您在处理异步函数时的正确时刻调用setState
。
在回调之外更改状态会导致一个简单的错误:
function() async {
setState(() {});
myState = await future;
}
这会导致问题,因为如果您的未来不能同步完成,则将在状态发生变化之前调用build方法。
通过使用回调,您必须执行以下操作:
function() async {
final value = await future;
setState(() {
myState = value;
});
}
这一次不会造成问题,因为在setState之前等待着将来。
我不能进行异步回调并且仍然遇到问题吗?
不。因为setState方法在内部检查回调是否不返回将来。如果这样做,它将抛出。
所以以下是不可能的:
setState(() async {
myState = await future;
});