Redux中Switch-Case与函数对象式Reducer的差异及报错问题
问题分析与解决方案
嘿,我一眼就瞅到你代码里的问题啦!咱们先聊聊两种写法的核心差异,再给你把bug fix掉~
核心执行差异:返回值的缺失
你改写后的reducer和原switch-case写法的关键区别在于:当匹配到对应action类型时,你没有返回处理函数的执行结果!
原switch-case写法的逻辑
原代码里每个case分支都明确用return返回了新的state对象,default分支也返回了原state——这保证了reducer无论何时都会返回一个合法的state值(要么是新状态,要么是初始/原状态):
function reducer(state = initialState, action) { switch (action.type) { case TOGGLE_SWITCH: return { ...state, light: !state.light }; // 明确返回新状态 case INCREMENT: return { ...state, counter: state.counter + action.diff }; // 明确返回新状态 case DECREMENT: return { ...state, counter: state.counter - 1 }; // 明确返回新状态 default: return state; // 兜底返回原状态 } }
改写后写法的问题
你改写的代码里,当action.type存在于tasks对象中时,只是调用了对应的处理函数,但没有把函数的返回值return出去:
// 错误代码片段 if (tasks.hasOwnProperty(action.type)) tasks[action.type](state, action); else return state;
这意味着,当匹配到action类型时,处理函数确实执行并生成了新state,但这个新state没有被reducer返回——此时reducer会默认返回undefined。而Redux要求reducer必须始终返回一个合法的state值,undefined会直接导致store.getState()抛出类型错误。
修正后的代码
只需要在调用处理函数时加上return,就能和原switch-case写法的逻辑完全一致了:
const reducer = (state = initialState, action) => { const tasks = { TOGGLE_SWITCH(state, action) { return { ...state, light: !state.light }; }, INCREMENT(state, action) { return { ...state, counter: state.counter + action.diff }; }, DECREMENT(state, action) { return { ...state, counter: state.counter - 1 }; }, }; if (tasks.hasOwnProperty(action.type)) { return tasks[action.type](state, action); // 加上return,返回处理后的新状态 } else { return state; } };
额外优化建议
把tasks对象提到reducer外面,避免每次调用reducer都重新创建这个对象,能稍微提升一点性能:
// 把处理函数对象提取到外部,只创建一次 const taskHandlers = { TOGGLE_SWITCH(state, action) { return { ...state, light: !state.light }; }, INCREMENT(state, action) { return { ...state, counter: state.counter + action.diff }; }, DECREMENT(state, action) { return { ...state, counter: state.counter - 1 }; }, }; const reducer = (state = initialState, action) => { if (taskHandlers.hasOwnProperty(action.type)) { return taskHandlers[action.type](state, action); } return state; };
内容的提问来源于stack exchange,提问作者Hyeonseo Kim
相关产品推荐
相关产品推荐

