React中useEffect结合Firestore getDocs()首次获取数据返回空数组问题
问题原因及解决方案
1. 首次打印allData为空的核心原因
setAllData是异步的状态更新函数,你在调用temp()后立刻执行console.log("allData: ", allData),此时状态更新还未完成,打印的是组件初始化时的空数组。另外,你在querySnapshot.forEach里多次调用setAllData,每次触发的状态更新都是异步批量处理的,这也导致同一轮事件循环里看不到最新状态值。
2. 具体修正方案
方案一:批量收集数据后一次性更新状态
不要在forEach里逐个触发状态更新,先把所有博客数据收集到临时数组,再一次性设置状态,既减少状态更新次数,逻辑也更清晰:
import db from "./firebase"; useEffect(() => { console.log("use effect ran"); const fetchBlogs = async () => { const q = query(collection(db, "blogs")); const querySnapshot = await getDocs(q); // 批量收集数据 const blogList = []; querySnapshot.forEach((doc) => { blogList.push({ id: doc.id, title: doc.data().title, content: doc.data().content, }); }); // 一次性更新状态 setAllData(blogList); }; fetchBlogs(); }, []);
方案二:正确查看更新后的状态
如果要确认allData是否更新成功,不要在同一个useEffect里立刻打印,新增一个监听allData的useEffect:
useEffect(() => { console.log("allData updated: ", allData); }, [allData]);
当allData状态更新完成后,这个useEffect会自动触发,打印出最新的数组内容。
关于修改代码后能看到数据的原因
修改代码保存时,React热更新会保留组件上一次渲染的状态,此时allData已经是更新后的值,所以重新触发useEffect时,打印的是之前更新后的状态,而非初始空数组。
内容的提问来源于stack exchange,提问作者io.19
相关产品推荐
相关产品推荐

