Redux combineReducers状态嵌套问题求助:为何需重复属性名取值?
问题原因与解决方案
你的问题出在拆分后的reducer职责划分错误,每个reducer都在管理整个状态对象,而不是自己负责的那一小块状态,导致combineReducers后状态结构嵌套了一层。
错误根源分析
- 你给
heroPosX和heroPosY这两个reducer的初始状态都是整个initialState对象,而不是各自对应的数值(比如initialState.heroPosX)。 - 处理
MOVE_X/MOVE_Yaction时,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
相关产品推荐
相关产品推荐

