3

在我的 Flutter 小部件中,我有一个StreamBuilder检查snapshot.hasError,在这种特定情况下,它将返回我的ErrorRetryWidget().

builder: (context, AsyncSnapshot<MyObject> snapshot) {
...
    if (snapshot.hasError) {
        return ErrorRetryWidget();
    }
}

只是显示ErrorRetryWidget()一条错误消息和一个重试按钮。当您按下此按钮时,我将按钮文本替换为进度指示器。因此我需要使这个小部件有状态,因为它的状态包含一个isRetrying我在 中设置为 false 的变量,initState然后在按下后设置为 true。

按下按钮时,ErrorRetryWidget通过 a 告诉父VoidCallback级重新触发流逻辑。它运作良好,但问题是如果错误再次出现,我StreamBuilderErrorRetryWidget再次“返回”。

构造函数被称为新时间,但不是initState。我怎样才能让它在每次重新创建小部件时重置状态?因此,isRetrying已经(或仍然)设置为 true。

我发现的唯一快速解决方案是在我的错误小部件中实现这一点:

@override
void didUpdateWidget(covariant oldWidget) {
    super.didUpdateWidget(oldWidget);
    setState(() {
        retrying = false;
    });
  }

不确定这是一个好习惯。

4

2 回答 2

5

传递一个唯一的键,让它创建一个新的小部件。

if (snapshot.hasError) {
    return ErrorRetryWidget(key: UniqueKey());
}
于 2020-06-11T21:27:33.673 回答
2

正如您所说,我使用 didUpdateWidget 来重置有状态小部件的状态。它在动画中也很有用。

我要添加的唯一评论是不要像您那样使用 setState,因为当框架调用 didUpdateWidget 时,它会立即调用 build。因此,您不必在 didUpdateWidget 中触发构建调用。它最终调用 build 两次。

@override
void didUpdateWidget(covariant oldWidget) {
    super.didUpdateWidget(oldWidget);
    retrying = false;
  }
于 2021-02-19T21:20:58.743 回答