Flutter Streambuilder 会不断地重建。

10

我有一个监听Firestore的流构建器,它基本上可以工作。主要问题是streambuilder不断重建(如果不会浪费额外读取次数,那就没有关系,但是我想它会导致这个问题)。当主页面第一次构建时,当我转到另一页时,它会再次构建,当我弹回到主页面时,它会再次重建。

代码:

class _RequestsListState extends State<RequestsList> with AutomaticKeepAliveClientMixin {
  final Map<String, List<Post>> posts = {};
  final List<String> postsUserIDs = [];

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);

    print('RequestsList');
    User cUser = InheritedUser.of(context).user;

    return StreamBuilder<List<Post>>(
        initialData: cUser.posts,
        stream: APIs().posts.auPostsStream(cUserID: cUser.userID),
        builder: (context, snap) {
          if (snap.hasError) {
            print('AUPostsList.dart StreamBuilder Error: ${snap.error}');
            return null;
          } else {

            print('POSTS LENGTH');
            print(snap.connectionState);
            print(cUser.posts.length);

            this.posts.clear();
            this.postsUserIDs.clear();

            snap.data.forEach((post) {
              if (this.posts[post.user.documentID] == null) {
                this.posts[post.user.documentID] = [post];
              } else {
                this.posts[post.user.documentID].add(post);
              }

              if (!this.postsUserIDs.contains(post.user.documentID)) {
                this.postsUserIDs.add(post.user.documentID);
              }
            });

            return ListView.separated(
                controller: widget.scrollController,
                physics: BouncingScrollPhysics(),
                shrinkWrap: true,
                padding: EdgeInsets.only(top: 0.0),
                itemBuilder: (context, index) => RequestItem(posts: this.posts[this.postsUserIDs[index]]),
                separatorBuilder: (context, index) => Container(),
                itemCount: this.postsUserIDs.length);
          }
        });
  }
}
第二,当我切换到第二页时,数组被清空了。我没有在任何地方清除它,所以我不确定为什么在点击项目后会清空数组...
日志:
Reloaded 0 of 773 
libraries in 169ms.
flutter: ChatsList
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 1
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 0
flutter: ChatsList
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 0
flutter: ChatsList

2
你能解决这个问题吗? - Yashank
2个回答

1

我知道现在已经有点晚了,但是将流移出构建上下文,可以通过使用您的init方法,或者使用provider在服务文件中调用来完成我的设置。如果你成功了,请让我知道。


对我来说,流上的 distinct 方法有助于避免不必要的重建。 - Till Friebe

0

你的假设是正确的...因为StreamBuilder在你的Build方法中,每次Widget被实例化时都会从Firestore读取。

所以在这种情况下,使用AutomaticKeepAliveClientMixin来保持Widget状态不会有帮助。

Wesley是正确的 - 你应该使用init方法来创建你的stream - 这样stream只会被调用一次。查看这个答案获取更多信息


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接