10

Firestore をリッスンするストリーム ビルダーがあり、ちょっとうまくいきます。主な問題は、ストリームビルダーが再構築を続けることです (追加の読み取りに費用がかからない場合は心配ありませんが、費用がかかる場合は、私が想定している問題です)。メイン ページが最初にビルドされると、別のページに移動すると再度ビルドされ、メイン ページに戻ると 3 回目の再ビルドが行われます。

コード:

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);
          }
        });
  }
}

次に、2 番目のページに移動すると、配列が空になります。どこにもクリアしていないので、アイテムをタップした後に配列を空にする理由がわかりません...

ログ:

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
4

2 に答える 2

1

これが遅れていることはわかっていますが、init メソッドを使用するか、プロバイダーを使用してサービス ファイルで呼び出しを行うかのいずれかで、ストリームをビルド コンテキストの外に移動することが、私のセットアップ方法です。あなたが正しく来たかどうか私に知らせてください。

于 2020-09-30T19:58:19.207 に答える
0

あなたの仮定は正しいです... StreamBuilder は Build メソッドにあるため、ウィジェットがインスタンス化されるたびに Firestore から読み取られます。

したがって、この場合AutomaticKeepAliveClientMixin、ウィジェットの状態を維持するために使用しても役に立ちません。

Wesley の言うとおりです。ストリームを作成するには init メソッドを使用する必要があります。この方法では、ストリームは 1 回だけ呼び出されます。詳細については、この回答を確認してください

于 2021-12-07T12:16:44.883 に答える