Redux 同时向Store提交date、time属性仅单个生效的问题咨询
问题根因
- 你的
dateTimeReducer在处理action、返回新状态时,没有保留原状态的其他属性,直接用仅包含单个字段的对象替换了整个reducer管理的状态,导致连续dispatch两个action时,先存入的字段被后续action完全覆盖。
核心违反了Redux不可变更新的基本要求:新状态必须是完整的、包含所有需要保留字段的全新对象,不能只返回要更新的部分字段
具体执行流程完全对应你遇到的现象:
- 你依次调用两个dispatch方法时,先触发
setDateaction,reducer按你写的代码直接返回{ date: action.payload }——原状态里的time属性被整个丢弃,新状态里只剩date字段。 - 紧接着触发
setPickedCellaction,reducer拿到的当前状态是上一步仅含date字段的对象,这时代码直接返回{ time: action.payload }——刚才存好的date字段又被整个覆盖,最终状态里只剩最后一次dispatch传入的time字段。
为什么单独测试单个dispatch时功能看起来完全正常?
因为初始状态本身就是{ date: {}, time: {} },当你单独触发setDate时,虽然丢失了空的time属性,但你此时没有读取time字段,感知不到状态被覆盖;同理单独触发setPickedCell时,丢失的也是空的初始date属性,完全不会影响你对单个功能的测试判断。这和Redux是否支持存储对象、JS执行时序都没有关系。
修复方案
- 所有需要更新部分状态的case分支,返回新状态时必须先展开拷贝原state,再覆盖需要更新的目标字段,保证其他原有属性不被丢失。
你原来的错误reducer代码:
const dateTimeReducer = (state = initialState, action) => { switch (action.type) { case 'setDate': return { date: action.payload, } case 'setPickedCell': return { time: action.payload, } default: return state } }
修改为正确写法:
const dateTimeReducer = (state = initialState, action) => { switch (action.type) { case 'setDate': return { ...state, date: action.payload, } case 'setPickedCell': return { ...state, time: action.payload, } default: return state } }
修改后同时dispatch两个action时,两个字段都会被完整保留,不会出现互相覆盖的问题。
内容的提问来源于stack exchange,提问作者Rachael O'James
相关产品推荐
相关产品推荐

