为何useEffect引发无限重渲染?React新手技术求助
问题分析与解决
无限重渲染的原因
你把usersDragons放进useEffect依赖项,但钩子内部又调用setUsersDragons更新这个状态。由于数组是引用类型,每次setUsersDragons(usersDragonsFromDBArray)都会生成全新的数组对象——哪怕内容和之前完全一致,React也会判定依赖项发生变化,进而重新触发useEffect。这就形成了「触发useEffect→更新状态→依赖变化→再次触发useEffect」的无限循环。
另外,当前代码的依赖项里缺少currentUser,但钩子逻辑完全依赖currentUser的存在才能执行,这也是「移除usersDragons后钩子完全不执行」的原因:组件加载时currentUser可能还未初始化,后续currentUser变化时,因为不在依赖列表里,钩子也不会触发。
修复后的代码
useEffect(() => { async function checkForUsersDragons(currentUser) { try { const usersDragonsFromDB = await getUsersDragonsFromDB(currentUser.uid); const usersDragonsFromDBArray = Object.values(usersDragonsFromDB); if (usersDragonsFromDBArray.length > 0) { setUsersDragons(usersDragonsFromDBArray); } else { console.log("No dragons for this user"); } } catch (error) { console.error("Error fetching dragons:", error); } } if (currentUser) { checkForUsersDragons(currentUser); } }, [currentUser]); // 将依赖项改为currentUser,匹配实际触发逻辑
额外优化建议
如果需要在usersDragons自身变化时执行其他操作,不要把它和拉取数据的逻辑混在同一个useEffect里。拉取数据的逻辑只需要在用户身份(currentUser)变化时触发,避免不必要的数据库请求。
若确实要监听usersDragons的变化,可以单独写一个useEffect处理:
useEffect(() => { // 这里编写usersDragons变化时需要执行的逻辑,比如更新本地缓存、触发UI联动等 }, [usersDragons]);
内容的提问来源于stack exchange,提问作者Cranky Dragon
相关产品推荐
相关产品推荐

