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

Redux combineReducers状态嵌套问题求助:为何需重复属性名取值?

问题原因与解决方案

你的问题出在拆分后的reducer职责划分错误,每个reducer都在管理整个状态对象,而不是自己负责的那一小块状态,导致combineReducers后状态结构嵌套了一层。

错误根源分析

  1. 你给heroPosX和heroPosY这两个reducer的初始状态都是整个initialState对象,而不是各自对应的数值(比如initialState.heroPosX)。
  2. 处理MOVE_X/MOVE_Y action时,reducer返回的是包含整个状态的新对象({...state, heroPosX: ...}),而不是直接返回更新后的坐标数值。

这就导致combineReducers之后,store的状态结构变成了:

{
  heroPosX: { heroPosX: 初始值, heroPosY: 初始值 },
  heroPosY: { heroPosX: 初始值, heroPosY: 初始值 }
}

所以你必须写state.heroPosX.heroPosX才能拿到实际数值。

修复步骤

1. 修改heroPosition.js的reducer代码

让每个reducer只负责管理自己对应的数值:

import { initialState } from "./initialState";

// heroPosX只管理x坐标数值
export function heroPosX(state = initialState.heroPosX, action) {
  switch (action.type) {
    case "MOVE_X":
      return state + 10; // 直接返回新的x数值
    default:
      return state;
  }
}

// heroPosY只管理y坐标数值
export function heroPosY(state = initialState.heroPosY, action) {
  switch (action.type) {
    case "MOVE_Y":
      return state + 10; // 直接返回新的y数值
    default:
      return state;
  }
}

2. 保持Hero组件的useSelector不变

现在state.heroPosX就是你要的坐标数值了,不需要再嵌套访问:

const heroPosX = useSelector((state) => state.heroPosX);
const heroPosY = useSelector((state) => state.heroPosY);

补充说明

之前用单个reducer时没问题,是因为单个reducer负责管理整个状态对象,返回完整状态是正确的。但拆分后每个reducer只对应状态树的一个分支节点,必须只返回该节点的更新后值,combineReducers会自动把这些分支组合成完整的状态树。

内容的提问来源于stack exchange,提问作者Jon Pitans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:52:02