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

Flutter 颤振:从子StreamBuilder更新有状态小部件,flutter,google-cloud-firestore,Flutter,Google Cloud Firestore,我已经编写了一些简化代码,希望firestore数据的条件能够更新父窗口小部件 我得到一个错误:setState()或markNeedsBuild()在生成过程中被调用 如何从StreamBuilder内部更新myVar的状态?更新myVar后,将不会访问StreamBuilder,而只访问正在等待的文本。。。应该显示 编辑:我更新了myVar以用作Firestore的文档ID。为了澄清,我希望能够从StreamBuilder内部更新StreamBuilder的文档。换句话说,正如问题所说,从子

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

我得到一个错误:setState()或markNeedsBuild()在生成过程中被调用

如何从StreamBuilder内部更新myVar的状态?更新myVar后,将不会访问StreamBuilder,而只访问正在等待的文本。。。应该显示

编辑:我更新了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);
          });
  }
}
类MyWidget扩展了StatefulWidget{
MyWidget({Key})
:super(key:key);
@凌驾
_MyWidgetState createState(){
返回_MyWidgetState();
}
}
类_MyWidgetState扩展状态{
字符串myVar=“someID”;
@凌驾
小部件构建(构建上下文){
如果(myVar==null){
//更新myVar async,以便重新呈现StreamBuilder
asyncFunctUpdate(myVar);//编辑:如果从asyncFuncUpdate(myVar)执行setState,则最终使其工作。然后(()=>setState)
返回文本(“等待…”);
}
其他的
返回流生成器(
流:Firestore.instance
.collection(“myCollection”)
.文件(myVar)
.snapshots(),
生成器:(上下文,订单快照){
如果(!orderSnapshot.data.exists)
设置状态(){
myVar=null;
});
否则返回文本(orderSnapshot);
});
}
}
解决方法: 在我的例子中,只返回StreamBuilder中的按钮和onPressed函数中的setState更简单

解决方案:
通常,您不必执行现在正在执行的操作,而可以在.then子句(参见上面的代码)中执行setState。您可以返回文本(“等待…”);马上打电话给setState。对你来说,这是一个更好的决定。您响应来自流的事件,并且必须根据当前状态返回内容

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);
      });
返回StreamBuilder(
流:Firestore.instance
.collection(“myCollection”)
.document(“myDocument”)
.snapshots(),
生成器:(上下文,订单快照){
如果(!orderSnapshot.data.exists)
返回文本(“等待…”);
否则返回文本(orderSnapshot);
});

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

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

您可以避免在特定用例中使用状态,如:

@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);
          }
        });
  }
@覆盖
小部件构建(构建上下文){
返回流生成器(
流:Firestore.instance
.collection(“myCollection”)
.document(“myDocument”)
.snapshots(),
生成器:(上下文,订单快照){
如果(!orderSnapshot.data.exists){
返回文本(“等待…”);
}否则{
返回文本(orderSnapshot);
}
});
}

您应该创建一个
async
方法,并从流生成器中调用它。类似于:
void setMyVar(String var)async{setState((){myVar=var})
。这应该在生成完成后运行。@DanyData调用使用async关键字的函数,即使它不需要,也不会改变该函数的执行方式-它仍然会在生成完成之前同步执行。至于实际的解决方案,请检查Artem的回答。这是真的调用async不起作用。它返回相同的错误。我更新了代码,因为它没有足够清楚地描述我的问题。嘿,Artem,我在简化的代码中不够清楚,但在实际代码中有一个变量myDocument,在显示“Waiting…”的事件中应该更改。我不希望StreamBuilder被“访问”,换句话说,已呈现。很抱歉,我不够清楚。感谢您的回答,但我必须更新我的问题,因为此答案无法解决我的问题。经过进一步调查,似乎可以从.then子句而不是在异步函数中执行setState