Firebase v9 onSnapShot 在異步函數中,同時在 useEffect React 中被調用

dwix

我正在使用 Firebase v9,我正在構建一個聊天應用程序,我需要在調用 onSnapShot 獲取聊天數據之前做一些異步工作:

      const getChat = async () => {
        // I need to await for user data before doing anything else.
        // I'll need some user data to build the query which
        // I'll be using in onSnapShot later on.
        const user = await getUserData();
        console.log(user);
        
        const collectionRef = collection(db, "messages");
        const q = query(
        collectionRef, where("user_id", "==", user.id), orderBy("createdAt"));
    
        const unsubscribe = onSnapshot(q, (snapshot) => {
          const data = snapshot.docs.map((doc) => {
            const entry = doc.data();
    
            return {
              id: doc.id,
              message: entry.message,
            };
          });
          setChatLines(data);
        });
    
        return unsubscribe;
      };

然後在 useEffect 中:

  useEffect(() => {

    const unsubscribe = getChat();

    return () => {
      unsubscribe();
    };
  }, []);

這裡的問題是這unsubsribe是一個承諾,因為它getChat是異步的,但我仍然想getUserData()在調用 onSnapShot 之前等待,因為稍後我將需要 onSnapShot 查詢中的用戶數據。

有沒有辦法使這項工作能夠unsubscribe在 useEffect 清理功能中正確進行?

德魯里斯

在這種情況下,我建議使用 React ref 來保存要在useEffect清理函數中使用的取消訂閱函數。

const unsubscribeRef = React.useRef();

const getChat = async () => {
  const user = await getUserData();
   
  const collectionRef = collection(db, "messages");
  const q = query(
  collectionRef, where("user_id", "==", user.id), orderBy("createdAt"));

  const unsubscribe = onSnapshot(q, (snapshot) => {
    const data = snapshot.docs.map((doc) => {
      const entry = doc.data();

      return {
        id: doc.id,
        message: entry.message,
      };
    });
    setChatLines(data);
  });

  unsubscribeRef.current = unsubscribe;
};

useEffect(() => {
  getChat();

  return () => {
    unsubscribeRef.current?.();
  };
}, []);

另一種方法是在useEffect鉤子回調主體中添加一個額外的異步函數,它可以等待getChatPromise 解析。

useEffect(() => {
  let unsubscribe;

  const getChatAndSubscribe = async () => {
    unsubscribe = await getChat();
  }
    
  getChatAndSubscribe();

  return () => {
    unsubscribe?.();
  };
}, []);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

React 和 firebase v9:在 onSnapshot 上動態設置路徑不起作用

React / Stripe / createPortalLink() 与 firebase v9

使用 React JS 在 Firebase v9 中创建文档时保存文档 ID

Firebase v9,无法从嵌套集合中获取文档

在異步函數中正確使用 useEffect 和 useState 調用

如何增加 Firebase 實時數據庫 (v9) 中的值

Firebase Web v9 升级打破了 react-firebase-hooks “useCollectionData()”

react + firebase unsubscribe 不是 useEffect 中的函数

React Firebase UseEffect Firestore

无法使用 Firebase v9 Modular React JS 读取未定义的属性(读取“indexOf”)

如何在 React 中将此代码从 Firebase Firestore v8 转换为 Firebase Firestore v9 Modular

React Native UseEffect API 調用

如何在react js中查詢firestore v9數據

如果在 React 的另一個組件中被調用,則檢測函數

如何在 Node 中初始化 Firebase V9 数据库

如何使用 Firebase Modular SDK V9 在 Firestore 中增加数据字段?

Firebase V9 在线状态

如何在firebase中使用onSnapshot?無法在我的應用程序中工作

React 和 Firebase Firestore V9 上一页分页返回“第一页”

在 setTimeout 中調用異步函數

Firebase onSnapShot不断通话

Firebase返回onSnapshot许诺

Firebase / Cloud Firestore:onSnapshot()与on()

無限調用 UseEffect UseSelector UseDispatch React.js

React+Typescript:修復 UseEffect Hook(回調 + 清理函數錯誤)

Firebase - 从函数中的 onSnapshot 事件返回值

如何使用 Firebase 的 onSnapshot 在 Svelte 中创建响应式语句?

Sveltekit 與 Firebase UI 身份驗證困難(v8/v9 和 signInSuccessWithAuthResult 回調有問題)

Firebase和React Hooks(useState和useEffect)