在 useEffect React 中调用异步函数中的 Firebase v9 onSnapShot
Firebase v9 onSnapShot in async function while being called in useEffect React
我正在使用 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
是异步的,但我仍然想在调用 onSnapShot 之前等待 getUserData()
,因为我需要稍后在 onSnapShot 查询中的用户数据。
有没有办法在 useEffect 清理函数中 unsubscribe
正确地完成这项工作?
在这种情况下,我建议使用 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
挂钩回调主体中添加一个异步函数,它可以等待 getChat
Promise 解析。
useEffect(() => {
let unsubscribe;
const getChatAndSubscribe = async () => {
unsubscribe = await getChat();
}
getChatAndSubscribe();
return () => {
unsubscribe?.();
};
}, []);
我正在使用 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
是异步的,但我仍然想在调用 onSnapShot 之前等待 getUserData()
,因为我需要稍后在 onSnapShot 查询中的用户数据。
有没有办法在 useEffect 清理函数中 unsubscribe
正确地完成这项工作?
在这种情况下,我建议使用 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
挂钩回调主体中添加一个异步函数,它可以等待 getChat
Promise 解析。
useEffect(() => {
let unsubscribe;
const getChatAndSubscribe = async () => {
unsubscribe = await getChat();
}
getChatAndSubscribe();
return () => {
unsubscribe?.();
};
}, []);