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

Redux action.type报错Cannot read properties of undefined排查

问题根源

这个报错和你写的reducer逻辑本身没关系,纯粹是useSelector用错了。
你对reducer的认知是对的:reducer只会被Redux store内部调用,正常场景下传入的action永远是带type字段的合法对象,不可能是undefined,这也是官方示例里从来不会给action加可选链的原因。
真正触发报错的是这行代码:const mySelector = useSelector(myReducer);
useSelector要接收的是状态选择函数,它的执行逻辑很简单:组件首次渲染、每次store状态更新的时候,会把整个Redux根state作为第一个参数传给你传进去的选择函数,根本不会传第二个参数。你把reducer直接塞给useSelector之后,选择器执行的时候就相当于调用myReducer(整个根state),第二个形参action就是undefined,这时候你访问action.type,当然会抛「Cannot read properties of undefined (reading 'type')」的错误。
至于你写action?.type的时候程序能跑,纯粹是歪打正着:可选链碰到undefined的action直接返回undefined,switch匹配不到任何case就走default分支,把传进来的第一个参数(也就是整个根state)原封不动返回,刚好你的state结构和你预期要取的内容对上了,看起来就像功能正常,本质是错误用法碰出来的巧合,根本不是正确实现。

修复方法
  1. 先确认你创建store的时候已经把myReducer正确注册进去了,参考写法:
import { configureStore } from '@reduxjs/toolkit'
import { myReducer } from './reducer'

export const store = configureStore({
  reducer: {
    // 这个key可以自定义,对应后面选择器取数的路径
    profile: myReducer
  }
})
  1. 改掉useSelector的错误传参,不要直接传reducer,写个简单的选择函数从根state里摘出你需要的片段就行:
const myDispatch = useDispatch();
// 错误写法:const mySelector = useSelector(myReducer);
// 如果你在store里给reducer配的key是profile,就这么写
const profileState = useSelector(state => state.profile);
  1. 把reducer里的action?.type改回标准的action.type就行,不需要加可选链。改完之后reducer只会被Redux内部调用,永远能拿到合法的action参数,不会再出这个类型错误:
export function myReducer(state = initialState, action) {
  switch (action.type) {
    case NAME_UPDATED: return { ...state, name: action.payload };
    default: return state;
  }
}
  1. 最后把模板里读状态的代码对应改下就完事:
<p>
  The Current value of <code>name</code> in the store is: <code>{profileState.name}</code>.
</p>
<button onClick={() => myDispatch(updateProfile('Updated Name'))}>
  Update Name
</button>

内容的提问来源于stack exchange,提问作者Chaudhry Talha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:18:14