Firebase快照迭代仅向React状态推送单个对象的问题求助
解决React状态更新只保留最后一个元素的问题
你这段代码的核心问题是循环内多次调用setEvents时,没正确利用React状态更新的函数式逻辑。因为setState是异步操作,每次循环里引用的events都是初始的空数组,导致每次更新都是把新元素加到空数组里,最终只有最后一次更新生效,所以数组里只剩一个元素。
修复方案一:先构建完整数组再一次性更新
先把Firebase返回的所有对象转换成目标格式,存入临时数组后再一次性更新状态,这样还能减少组件重渲染次数:
const [events, setEvents] = useState([]) const dummy = snapshot.val(); console.log(dummy) // 先把所有Firebase对象转换成需要的结构 const newEvents = Object.keys(dummy).map(keyName => { return { name: dummy[keyName]['name'], email: dummy[keyName]['email'], date: dummy[keyName]['Date']['startTime'], extra: { text:'Click for email', icon:"" } } }) // 一次性更新状态 setEvents(newEvents)
修复方案二:使用函数式更新(不推荐循环调用,仅作演示)
如果一定要在循环内更新状态,必须用setState的函数式写法,依赖参数里的当前状态数组,而非外部的events变量:
const [events, setEvents] = useState([]) const dummy = snapshot.val(); console.log(dummy) // 遍历用forEach更合适,map是用来生成新数组的 Object.keys(dummy).forEach(keyName => { setEvents(prevArray => [...prevArray, { name: dummy[keyName]['name'], email: dummy[keyName]['email'], date: dummy[keyName]['Date']['startTime'], extra: { text:'Click for email', icon:"" } }]) })
额外说明
控制台多次输出是因为每次调用setEvents都会触发组件重渲染,循环几次就重渲染几次,所以console.log(dummy)会执行多次。用方案一的话只会重渲染一次,性能更优。
内容的提问来源于stack exchange,提问作者like who
相关产品推荐
相关产品推荐

