You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React useReducer+useContext状态在reducer与消费组件间不一致如何解决

问题原因

你遇到的count多减1的问题核心出在reducer的实现不符合不可变数据要求:

  1. 你在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:27:03