为什么 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,因此在 initStatesetState 回调之外发生的任何成员变量突变都将被标记为可疑。

如果您刚刚开始使用 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;
});