React useState使用Spread operator从Firebase拉取数据填充状态遇覆盖问题
问题根源
这是React状态更新的闭包捕获+异步批处理特性导致的:
- 你当前useEffect回调函数捕获的是本次effect执行时的
bookings状态值(你在查询前调用了setBookings([]),因此本次作用域内的bookings始终是空数组) - 循环内多次调用
setBookings([...bookings, doc.data()])时,每次展开的都是初始空数组,连续的状态更新会被React批处理合并,最终仅保留最后一次更新的结果。
最优解决方案:批量更新状态
优先把所有查询结果收集后一次性更新状态,仅触发一次重渲染,性能最优:
.then((querySnapshot) => { // 批量处理所有文档生成数组 const newBookings = querySnapshot.docs.map(doc => doc.data()); // 一次性更新状态 setBookings(newBookings); setLoading(false); })
备选解决方案:使用函数式状态更新
如果需要逐条追加数据,可以使用setState的函数式写法,直接读取最新的状态值,不受闭包影响:
querySnapshot.forEach((doc) => { console.log(doc.data()); // 函数参数prev会自动传入最新的bookings状态 setBookings(prev => [...prev, doc.data()]); });
内容的提问来源于stack exchange,提问作者Olly
相关产品推荐
相关产品推荐

