React中useState数组仅最后一个元素更新问题求助
useState数组/对象更新仅最后一个元素生效的问题解决
你的问题核心在于闭包捕获的旧状态与useState异步更新的特性冲突:
useEffect依赖为空数组,仅执行一次,此时闭包里的arr是组件初始化时的初始值["NOT CHANGED","NOT CHANGED"]。循环中每次调用setArr都是基于这个初始数组拷贝修改,两次更新互相覆盖——第一次修改索引0后,第二次仍用初始数组修改索引1,最终只有最后一次更新生效。
方案1:一次性完成所有修改再更新状态
无需循环调用setArr,先完成数组的所有修改操作,再一次性提交更新,避免状态覆盖:
function Sub({arr, setArr}) { useEffect(() => { const arr_copy = arr.slice(); for(let i = 0; i < 2; i++){ arr_copy[i] = i; } setArr(arr_copy); },[]) return <p> </p> }
方案2:函数式更新(适配连续依赖上一次状态的场景)
如果必须分多次更新(比如每次修改依赖上一次状态结果),使用setState的函数式写法,它会接收上一轮的最新状态作为参数,而非闭包里的旧状态:
function Sub({arr, setArr}) { useEffect(() => { for(let i = 0; i < 2; i++){ setArr(prevArr => { const newArr = prevArr.slice(); newArr[i] = i; return newArr; }); } },[]) return <p> </p> }
字典(对象)场景的适配
针对对象更新的同类问题,逻辑完全一致:
- 一次性修改:先拷贝对象并完成所有属性修改,再调用更新函数
- 函数式更新:基于上一次对象状态做修改
示例代码:
// 对象的函数式更新示例 setObj(prevObj => { return {...prevObj, [key]: newValue}; });
内容的提问来源于stack exchange,提问作者Thornsider3
相关产品推荐
相关产品推荐

