繁体   English   中英

Flutter:从子 StreamBuilder 更新有状态小部件

[英]Flutter: update stateful widget from child StreamBuilder

我已经编写了一些简化的代码,我希望 Firestore 数据的条件能够更新父小部件。

我收到错误:在构建期间调用了 setState() 或 markNeedsBuild()。

如何从 StreamBuilder 中更新 myVar 的 state? 更新 myVar 后,不会访问 StreamBuilder,而只会显示文本 Waiting...。

编辑:我更新了 myVar 以用作 Firestore 的文档 ID。 为了澄清,我希望能够从 StreamBuilder 内部更新 StreamBuilder 的文档。 换句话说,正如问题所说,从子 StreamBuilder 更新有状态小部件。

class MyWidget extends StatefulWidget {
  MyWidget({Key key})
      : super(key: key);

  @override
  _MyWidgetState createState() {
    return _MyWidgetState();
  }
}

class _MyWidgetState extends State<MyWidget> {
  String myVar = "someID";

  @override
  Widget build(BuildContext context) {
    if (myVar == null) {
      // update myVar async, so that StreamBuilder will be re-rendered
      asyncFunctUpdate(myVar); // edit: finally got it to work if doing setState from asyncFuncUpdate(myvar).then(()=>setState)
      return Text("Waiting...");
    }
    else
      return StreamBuilder<DocumentSnapshot>(
          stream: Firestore.instance
              .collection('myCollection')
              .document(myVar)
              .snapshots(),
          builder: (context, orderSnapshot) {
            if (!orderSnapshot.data.exists)
              setState(() {
                myVar = null;
              });
            else return Text(orderSnapshot);
          });
  }
}

解决方法:在我的情况下,像通常从 onPressed 函数一样从 StreamBuilder 和 setState 返回按钮更简单。

解决方案:不要从异步 function 中执行 setState,而是在 .then 子句中执行(参见上面的代码)

一般来说,你不必做你现在正在做的事情。 你可以做 return Text ("Waiting..."); 立即无需调用 setState。 在您的情况下,这是一个更好的决定。 您响应来自 stream 的事件,并且必须根据当前 state 返回内容

return StreamBuilder<DocumentSnapshot>(
      stream: Firestore.instance
          .collection('myCollection')
          .document('myDocument')
          .snapshots(),
      builder: (context, orderSnapshot) {
        if (!orderSnapshot.data.exists)
            return Text("Waiting...");
        else return Text(orderSnapshot);
      });

您可以使更新异步,就像将其放在匿名异步回调中一样

() async {
    setState();
}();

或者

您可以避免在该特定用例中使用 state,例如:

@override
  Widget build(BuildContext context) {
      return StreamBuilder<DocumentSnapshot>(
        stream: Firestore.instance
          .collection('myCollection')
          .document('myDocument')
          .snapshots(),
        builder: (context, orderSnapshot) {
          if (!orderSnapshot.data.exists) {
            return Text("Waiting...");
          } else {
            return Text(orderSnapshot);
          }
        });
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM