为什么setState会关闭?

时间:2017-06-05 23:50:48

标签: dart flutter

setState()接受函数只是为了立即调用它然后请求重建的好处是什么?特别是,使用户明确地调用"重建"的优点是什么?类型功能?

2 个答案:

答案 0 :(得分:18)

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

如果您遵循仅在setState关闭内变更成员变量的惯例,那么您将避免重构某些代码并意外删除对setState的调用的情况,或者不必要地致电setState。如果您的State已卸载,Flutter可能会失败一个断言,因此一旦您开始尝试改变成员而不是最终,您就会知道出现问题。

最终可能会analyzer warning强制执行setState在变更State的成员时始终被调用,因此任何成员变量突变发生在initState之外或setState回调将被标记为可疑。

如果您刚开始使用Flutter中的州,请查看Flutter widgets tour。我发现使用FutureBuilderStreamBuilderAnimatedWidgetAnimatedBuilder可以更优雅地处理我呼叫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;
});