React useReducer+useContext状态在reducer与消费组件间不一致如何解决
问题原因
你遇到的count多减1的问题核心出在reducer的实现不符合不可变数据要求:
- 你在reducer中直接修改了传入的原state对象:
if (action.payload.playerid === 1) { state.player1!.targets = [...newTargets]; }
reducer要求是纯函数,禁止直接修改传入的state,否则会污染原始状态。
2. React 18 开发环境默认开启严格模式,会重复调用reducer两次来检测函数纯度,你这种直接修改原state的不纯逻辑,就会导致减1操作被执行两次,最终呈现出count少2的效果。
修复方案
重构reducer逻辑,全程基于原state做拷贝修改,完全不触碰原state对象,参考实现如下:
const isPlayer1 = action.payload.playerid === 1; const currentPlayer = isPlayer1 ? state.player1! : state.player2!; // 用map生成新的targets数组,仅修改命中的目标count const updatedTargets = currentPlayer.targets.map(target => target.id === action.payload.targetid ? {...target, count: target.count - 1} : target ); const updatedPlayer = { ...currentPlayer, targets: updatedTargets }; // 直接返回全新的state对象,不修改原state的任何属性 return { ...state, player1: isPlayer1 ? updatedPlayer : state.player1, player2: isPlayer1 ? state.player2 : updatedPlayer };
这种实现下所有修改都基于新生成的对象,哪怕严格模式重复调用reducer,每次计算都是基于最初的原始state,最终结果一致,不会出现重复扣减的问题。
内容的提问来源于stack exchange,提问作者Martin Frank Moesby Petersen
相关产品推荐
相关产品推荐

