Firebase实时数据库结合React时forEach循环无限执行问题
解决Firebase实时数据获取导致的无限循环问题
问题根源
- Hook使用违规:你把
useEffect嵌套在了onAuthStateChanged的回调内部,而且useEffect的第一个参数传了对象而非函数。React要求Hook必须在组件顶层调用,不能嵌套在任何回调、循环或条件判断里,错误写法会导致每次组件渲染都重复执行数据获取逻辑。 - 状态更新触发循环:在
rows.forEach里多次调用setMyArray,每次状态更新都会触发组件重新渲染,而错误的Hook逻辑又会再次发起数据库请求,进而再次更新状态,形成无限循环。 - uid硬编码为空:代码里
const uid = '';会导致数据库路径无效,无法正确获取目标数据。
修复方案
- 将
onAuthStateChanged逻辑移到组件顶层的useEffect内部,遵循Hook使用规则; - 一次性构建完整数组后再更新状态,避免多次调用
setMyArray触发重复渲染; - 从
user对象中正确获取uid,保证数据库路径有效; - 给
useEffect添加依赖项,仅当路由参数变化时重新获取数据。
修复后的完整代码
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { getDatabase, ref, get, child } from 'firebase/database'; import { getAuth, onAuthStateChanged } from 'firebase/auth'; function About() { const params = useParams(); const [title, setTitle] = useState(''); const [myArray, setMyArray] = useState([]); useEffect(() => { const auth = getAuth(); // 订阅用户登录状态变化,返回取消订阅函数 const unsubscribe = onAuthStateChanged(auth, (user) => { if (!user) { setMyArray([]); return; } const uid = user.uid; const db = getDatabase(); const dbRef = ref(db); const targetPath = `users/${uid}/${params.hey}`; get(child(dbRef, targetPath)) .then((snapshot) => { if (snapshot.exists()) { const snap = snapshot.val(); const rows = snap['rows']; // 一次性生成目标数组,只更新一次状态 const newArray = rows.map((_, index) => `${index}`); setMyArray(newArray); } else { console.log("目标数据不存在"); setMyArray([]); } }) .catch((error) => { console.error("获取数据失败:", error); setMyArray([]); }); }); // 组件卸载时取消登录状态监听,避免内存泄漏 return unsubscribe; }, [params.hey]); // 依赖路由参数,参数变化时重新获取数据 console.log('myArray', myArray); return ( <> <main> <h2>{title}</h2> <div> {myArray.map((e, index) => ( <div key={index}>{e}</div> ))} </div> </main> </> ); } export default About;
关键修复说明
- 把登录状态监听逻辑放在顶层
useEffect中,符合React Hook的使用规则,同时通过返回unsubscribe函数清理监听,避免内存泄漏; - 使用
rows.map一次性生成完整数组,仅调用一次setMyArray,减少不必要的组件渲染; - 从
user对象中获取真实uid,确保数据库查询路径有效; useEffect的依赖数组添加params.hey,保证路由参数变化时能重新获取对应数据。
内容的提问来源于stack exchange,提问作者like who
相关产品推荐
相关产品推荐

