useReducer问题:dispatch触发后action属性未定义报错排查
问题分析与解决方案
核心问题:Reducer的Switch Case穿透
你的reducer函数中所有switch case都缺少break语句,导致case穿透——匹配到某个case后,代码会继续执行后续所有case的逻辑,最终走到default分支将newState重置为原state;同时如果执行到需要访问action属性的分支(比如data-fetch)时,当前action可能没有对应属性,就会出现undefined错误。
比如当触发load-start类型的action时,代码会依次执行load-start、load-end、data-fetch的逻辑,最后执行default将state重置,不仅状态修改无效,还会在data-fetch分支中尝试访问不存在的action.data和action.more,直接触发报错。
修正方案
在每个case分支末尾添加break语句,阻止代码继续执行后续case:
const reducer = (state, action) => { let newState; switch (action.type) { case "load-start": newState = { ...state, loading: true }; break; case "load-end": newState = { ...state, loading: false }; break; case "data-fetch": newState = { ...state, more: action.more, data: [...state.data, ...action.data], iter: action.iter || state.iter + 1, }; break; default: newState = state; } return newState; };
额外检查点
- 排查未知dispatch触发:修复break后如果仍有报错,检查代码中是否有其他未注意到的dispatch调用,发送了不包含
data/more属性的data-fetch类型action。 - 优化useEffect依赖:当前useEffect依赖为空数组,只会在组件挂载时执行一次请求。如果需要根据
state.iter的变化重新请求数据,需将state.iter加入依赖数组,同时可结合useRef保存迭代值避免无限循环。
内容的提问来源于stack exchange,提问作者amazinglySK
相关产品推荐
相关产品推荐

