React useReducer修改状态内数组元素时每次累加2异常原因查询
问题原因
- Reducer 不纯,直接修改了原状态的引用值
你使用{...state}仅完成了对象的浅拷贝,只会复制 state 本身的第一层属性,而属性counts是引用类型的数组,浅拷贝后newState.counts和原state.counts指向内存中的同一个数组。执行newState.counts[0] += 1时,实际同时修改了原 state 中的数组值,违反了 Reducer 必须是纯函数、不能修改输入原 state 的要求。 - React 18 严格模式的重复检测逻辑
开发环境下如果应用外层包裹了<StrictMode>组件,React 会故意重复调用 Reducer、Effect 等函数,用来校验开发者是否编写了不纯的逻辑。因为你的 Reducer 会修改原 state,第一次调用已经改变了原 state 的数组值,第二次调用时会在已修改的基础上再次累加,最终两次调用后数值总共加了 2,就出现了后续点击每次累加 2 的异常。
修复方案
需要对数组也做一层拷贝,保证所有修改都在新的引用上执行,避免污染原 state:
const testReducer = (state) => { // 拷贝生成全新的数组 const newCounts = [...state.counts] newCounts[0] += 1 // 返回全新的状态对象 return { ...state, counts: newCounts } }
修改后 Reducer 为纯函数,即使被重复调用也会返回相同的结果,累加异常就会消失。同时建议补全 Reducer 的第二个 action 参数,方便后续扩展不同的操作类型。
内容的提问来源于stack exchange,提问作者Chris TF
相关产品推荐
相关产品推荐

