React项目useEffect中setTeams早于Firebase请求执行,如何调整执行顺序?
问题原因
你代码中遍历querySnapshot时,每次获取单个团队文档的get()请求都是独立的异步Promise,forEach方法不会等待这些异步任务执行完成,就会直接执行后续的setTeams,此时teamsList还没有被填充完整数据,所以会出现你遇到的问题。
解决方法
用Promise.all收集所有获取团队文档的异步请求,等所有请求都执行完成后再调用setTeams即可,修改后的代码如下:
useEffect(() => { // 保存监听函数用于后续卸载时取消 const unsubscribe = firebase.auth().onAuthStateChanged(async (user) => { if (user) { try { // 第一步:获取成员集合的查询快照 const querySnapshot = await firebase.firestore() .collectionGroup('members') .where('user', '==', user.uid) .get() // 第二步:收集所有获取团队文档的Promise const teamPromises = querySnapshot.docs.map(doc => { const teamId = doc.data().teamId return firebase.firestore().collection('teams').doc(teamId).get() }) // 第三步:等待所有团队文档请求全部完成 const teamDocs = await Promise.all(teamPromises) // 第四步:组装需要的数据结构 const teamsList = teamDocs.map(doc => ({ name: doc.data().name, teamID: doc.data().teamId, })) // 所有数据准备完成后再更新状态 setTeams(teamsList) } catch (err) { // 可根据业务需求补充错误处理逻辑 console.error('获取团队数据失败:', err) } } else { history.push("/logg-inn") } }) // 组件卸载时取消auth监听,避免内存泄漏 return () => unsubscribe() }, [history])
额外优化说明
- 新增了
onAuthStateChanged监听的取消逻辑,避免组件卸载后触发回调导致内存泄漏 - 给useEffect补充了
history依赖项,符合React Hooks的依赖规则 - 新增了错误捕获逻辑,方便排查请求异常问题
内容的提问来源于stack exchange,提问作者Daniel Olsen
相关产品推荐
相关产品推荐

