首页 > 解决方案 > Firebase firestore onSnapshot 在 useEffect 中无法正常工作

问题描述

我在使用 firebase 时遇到了一些问题,我正在使用 firestore onSnapshot 在 useEffect 中获取实时更新,如下所示:

  useEffect(() => {
  const unsubscribe = () => {
    firebase
      .firestore()
      .collection("posts")
      .orderBy("createdAt", "desc")
      .onSnapshot((post) => {
        const data = post.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setPosts(data);
        setLoading(false);
      });
  };
  return () => unsubscribe();
}, []);

但它不起作用,当组件挂载时我没有获取数据,奇怪的事实是,当我使用它而不返回取消订阅功能时,它工作得很好。像这样:

useEffect(() => {
firebase
  .firestore()
  .collection("posts")
  .orderBy("createdAt", "desc")
  .onSnapshot((post) => {
    const data = post.docs.map((doc) => ({
      id: doc.id,
      ...doc.data(),
    }));

    setPosts(data);
    setLoading(false);
  });

}, []);

我真的很想知道为什么第一种方法不起作用,这是理想的方法。我也在使用 React Router DOM,在这里你可以看到我的 Posts 组件,它在我获取数据时呈现一个 Post 组件。

     export default function Posts() {
      const [posts, setPosts] = useState([]);
      const [loading, setLoading] = useState(true);
    
    
      useEffect(() => {
        console.log("data listener...");
        const unsubscribe = () => {
          firebase
            .firestore()
            .collection("posts")
            .orderBy("createdAt", "desc")
            .onSnapshot((post) => {
              console.log("el console desde posts listeners..");
              const data = post.docs.map((doc) => ({
                id: doc.id,
                ...doc.data(),
              }));
              setPosts(data);
              setLoading(false);
            });
        };
        return () => unsubscribe();
      }, []);
//Not working
    
      return (
        <main className="posts">
          {loading && <h3>Loading posts...</h3>}
          {posts && posts.map((post) => <Post {...post} key={post.id} />)}
        </main>
      );
    }

此 Posts 组件由以下人员呈现:

  export default function Home() {
  return (
    <div className="home">
      <Nav />
      <Posts />
    </div>
  );
}

标签: reactjsfirebasegoogle-cloud-firestoreuse-effect

解决方案


那是因为您的侦听器被包装在另一个函数的一侧,因此除非您调用该函数,否则它不会被调用unsubscribe

const unsubscribe = () => { firebase.collection("posts").... }

试试这个

const unsubscribe = firestore.collection("posts")....

// now calling, unsubscribe() will detach the listenter

推荐阅读