首页 > 解决方案 > 如何在收听 Stream 时执行 setState()

问题描述

我希望你做得很好。我正在寻找一种可以在 Stream 中执行 setState 的方法。基本上我在这里所做的是,我从集合中获取数据,将其分配给一个名为 currentDocuments 的 List 变量,并在 ListView.builder() 中显示它。我没有使用 StreamBuilder,因为可以删除文档,但必须在本地删除,而不是从 Firestore 中删除。问题是当我将新文档添加到“mycollection”集合时,我收到以下消息:

如果您对不再出现在小部件树中的小部件(例如,其父小部件不再在其构建中包含该小部件)调用 State 对象上的 setState(),则会发生此错误。当代码从计时器或动画回调中调用 setState() 时,可能会发生此错误。首选的解决方案是取消计时器或停止在 dispose() 回调中收听动画。另一种解决方案是在调用 setState() 之前检查该对象的“已安装”属性,以确保该对象仍在树中。如果正在调用 setState(),则此错误可能表示内存泄漏,因为另一个对象在从树中删除此 State 对象后仍保留对该对象的引用。为避免内存泄漏,请考虑在 dispose() 期间中断对此对象的引用。

我已经尝试了很多使用“已安装”字段的方法,但我仍然收到了上面提到的消息。任何有关此问题的帮助将不胜感激。先感谢您。

代码:

_subscription = Firestore.instance.collection('mycollection').snapshots().listen((QuerySnapshot querySnapshot) {
      for(var i in querySnapshot.documentChanges){
        if(i.type == DocumentChangeType.added){
          if(!mounted){
            setState((){});
          }
          setState(() {
            currentDocuments = querySnapshot.documents;
          });
        }
      }
    });

标签: flutterdartstate

解决方案


_subscription = Firestore.instance.collection('mycollection').snapshots().listen((QuerySnapshot querySnapshot) {
      for(var i in querySnapshot.documentChanges){
        if(i.type == DocumentChangeType.added){
          if(mounted){
            setState(() {
             currentDocuments = querySnapshot.documents;
            });
          }
          
        }
      }
    });

如果小部件存在于树中,则这里mounted 将为真,但在您的代码中,有两个setState 调用将触发mounted 是否为真!!,仅在mounted 为真时使用/调用setState,


推荐阅读