React中第四个useEffect先执行,如何让依赖的第三个优先执行?
解决React useEffect执行顺序与依赖问题
你的问题核心不是第三个useEffect没优先执行,而是第三个里的onAuthStateChanged是异步回调——挂载时第三个useEffect会先注册监听,但回调里的setAuthUser和console.log是异步触发的,而第四个useEffect的同步代码(包括console.log)会在挂载时按代码顺序先执行,所以你看到第四个的log先出来。
要保证第四个useEffect能拿到正确的authUser,按以下方式修改:
- 给第四个useEffect添加依赖数组
[authUser],这样只有当authUser更新时才会执行,确保每次都用最新的用户数据 - 增加
authUser为空的判断,避免数据库路径拼接错误 - 添加清理函数,取消数据库的
onValue监听,防止内存泄漏
修改后的代码:
useEffect(() => { console.log("this is first useEffect", "first"); }); useEffect(() => { console.log("this is second useEffect", "second"); }); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { setLoading(true); if (user) { setAuthUser(user); setLoading(false); console.log("this is third useEffect", user); } else { setAuthUser(null); } }); return () => { unsubscribe(); }; }, []); useEffect(() => { // 当authUser为空时直接返回,避免错误 if (!authUser) return; const db = getDatabase(); console.log("this is fourth useEffect", authUser); const starCountRef = ref(db, `users/${authUser.uid}/addressData`); // 保存unsubscribe函数用于清理 const unsubscribe = onValue(starCountRef, (snapshot) => { const addresslist = []; snapshot.forEach((childSnapshot) => { const keyName = childSnapshot.key; const data = childSnapshot.val(); addresslist.push({ key: keyName, data: data }); }); setSavedAddress(addresslist); }); // 清理函数:取消监听 return () => unsubscribe(); }, [authUser]); // 添加authUser为依赖项
另外注意:第三个useEffect里的清理函数,原代码的listen()应该是unsubscribe()(已修正变量名更符合语义),否则可能无法正确取消auth状态监听。
内容的提问来源于stack exchange,提问作者user1450966
相关产品推荐
相关产品推荐

