为什么setState会关闭?

Col*_*son 18 dart flutter

setState()接受函数只是为了立即调用它然后请求重建有什么好处?特别是,与用户明确调用"重建"类型函数相比,有什么优势?

Col*_*son 21

当Flutter有一个"markNeedsBuild"函数时,开发人员最终只是随意调用它.当语法切换到时setState(() { ... }),开发人员更有可能正确使用API​​.从机器的角度来看,它们在功能上是等价的,但它们似乎从开发人员那里唤起了不同的代码.

如果您遵循仅在setState闭包内变异成员变量的约定,则可以避免重构某些代码并意外删除调用setStatesetState不必要地调用的情况.如果你State没有安装,Flutter可能会失败一个断言,所以一旦你开始尝试改变成员而不是最后,你就会知道出现问题.

最终可能会有一个分析器警告强制执行,setState在变更a的成员时总是被调用State,因此发生在回调initStatesetState回调之外的任何成员变量突变都将被标记为可疑.

如果您刚开始使用Flutter中的状态,请查看Flutter小部件之旅.我发现,很多地方我打电话的情况下setState,可以用更优雅的处理FutureBuilder,StreamBuilder,AnimatedWidget,或AnimatedBuilder,所以不要忘记考虑这些替代品,如果你发现自己调用setState了很多.

Adam Barth和Yaroslav Volovich对这个问题/答案做出了贡献.


Rém*_*let 10

为了完成 Colin 的回答,它还确保您setState在处理异步函数时在正确的时刻调用。

在回调之外改变你的状态可能会导致一个简单的错误:

function() async {
  setState(() {});
  myState = await future;
}
Run Code Online (Sandbox Code Playgroud)

这会导致一个问题,因为如果您的未来没有同步完成,则将在状态发生变化之前调用 build 方法。

通过使用回调,您将被迫执行以下操作:

function() async {
  final value = await future;
  setState(() {
    myState = value;
  });
}
Run Code Online (Sandbox Code Playgroud)

这一次,它不会引起问题,因为在 setState 之前等待了未来。

我不能进行异步回调并且仍然有问题吗?

否。因为 setState 方法在内部检查回调是否不返回未来。如果是这样,它会抛出。

所以以下是不可能的:

setState(() async {
  myState = await future;
});
Run Code Online (Sandbox Code Playgroud)