显示数据库中的所有帖子

Display all posts from database

我有一个Firestore合集,方案如下:

posts{
    uid{
        userPosts{
            postID{
                creation:
                postText:
            } 
        }
    }
}

我想显示所有的帖子,所以我做了相应的查询并将它们保存在 posts - 我稍后迭代的所有帖子的数组。

我这样做的问题是每次渲染都会添加相同的帖子。所以我每次都尝试设置数组,但这样代码就不会通过这些 posts && posts.length > 0 条件。

总的来说,我对 RN 和 JS 真的很陌生,但我期待的是

Nothing to show here

首先,然后是帖子列表。

完整组件:

import { Text, Pressable, FlatList, SafeAreaView } from "react-native";
import { globalStyles } from "../../styles/global";
import React, { useState, useEffect } from "react";
import { db } from "../../../firebase";
import Post from "../../API/Post";
import { collection, getDocs } from "firebase/firestore";

const FeedScreen = ({ navigation }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const getPostData = async () => {
      setPosts([]); // ---> Without this line the posts keeps adding each render
      const q = collection(db, "posts");
      const docSnap = await getDocs(q);
      docSnap.docs.map(async (item) => {
        const tmp = collection(db, "posts", item.id, "userPosts");
        const tmpSnap = await getDocs(tmp);
        tmpSnap.docs.map(async (element) => {
          setPosts((prev) => {
            prev.push(element.data());
            return prev;
          });
        });
      });
    };

    getPostData().catch(console.error);
    return;
  }, []);

  return (
    <SafeAreaView style={globalStyles.global}>
      {posts && posts.length > 0 ? (
        <FlatList
          data={posts}
          renderItem={({ item }) => (
            <Post
              post={item}
              navigation={navigation}
              style={globalStyles.list_of_posts}
            />
          )}
          keyExtractor={(item, index) => index.toString()}
        />
      ) : (
        <Text>Nothing to show here</Text>
      )}

      <Pressable
        title="edit"
        onPress={() => {
          navigation.navigate("CreatePost", { navigation });
        }}
        style={globalStyles.plus_btn}
      >
        <Text style={globalStyles.plus_btn_text}>+</Text>
      </Pressable>
    </SafeAreaView>
  );
};

export default FeedScreen;

如前所述,我是新手,所以我很想了解实际发生的情况以及如何正确地进行操作。

我认为 setPostsprev 值将始终为 [],因为如果您调用它,它不会立即更新。执行此操作的标准方法是在函数末尾调用 setPosts。你能试试这个吗?

useEffect(() => {
    const getPostData = async () => {
      const q = collection(db, "posts");
      const docSnap = await getDocs(q);
      const promises = docSnap.docs.map(async (item) => {
        const tmp = collection(db, "posts", item.id, "userPosts");
        const tmpSnap = await getDocs(tmp);
        return tmpSnap.docs.map((element) => element.data());
      });
      const arrayOfPosts = await Promise.all(promises);
      let newPosts = [];
      arrayOfPosts.forEach((posts) => {
        newPosts = [...newPosts, ...posts];
      });
      setPosts(newPosts);
    };

    getPostData().catch(console.error);
    return;
  }, []);