React+Redux中mapStateToProps无法获取state(值为undefined)求助
嘿,我找到你的问题啦!其实这和react-router一点关系都没有,问题出在你的Redux reducer里漏掉了一个关键的分支处理。
核心问题:Reducer缺少Default分支
Redux在创建Store的时候,会自动派发一个INIT类型的action来初始化应用状态。你的reducer里的switch语句只处理了UPDATE_FORM这个action类型,没有default分支——这就导致当INIT动作触发时,reducer没有返回任何值,直接返回了undefined,整个应用的state也就变成了undefined。
你看你的原reducer代码:
const insuranceReducer = (state = { productName: "" }, action) => { switch(action.type) { case "UPDATE_FORM": if(action.payload.productName){ state = { ...state, productName: action.payload.productName } } return state; // 这里没有处理其他action类型的分支! } }
当组件挂载调用mapStateToProps时,Redux会传入这个undefined的state,所以你访问state.productName就会抛出Cannot read property 'productName' of undefined的错误。
那为什么之前dispatch动作时控制台能正常打印状态呢?因为当你触发UPDATE_FORM动作时,reducer会进入对应的case分支,返回正确的state对象,所以中间件能拿到更新后的状态。但初始化阶段的问题已经埋下了。
修复步骤
只需要给你的reducer加上default分支,返回原state即可:
const insuranceReducer = (state = { productName: "" }, action) => { switch(action.type) { case "UPDATE_FORM": if(action.payload.productName){ state = { ...state, productName: action.payload.productName } } return state; // 新增default分支,处理所有未匹配的action default: return state; } }
额外优化建议
你的reducer里的if(action.payload.productName)判断有个小问题:如果用户在输入框里清空内容(输入空字符串),这个条件就不成立,state里的productName不会被更新为空。考虑到你的dispatch是通过[event.target.name]来动态传参的,建议直接把payload合并到state里,这样以后扩展其他表单字段也不用修改reducer:
case "UPDATE_FORM": return { ...state, ...action.payload };
这样不管payload里是productName还是其他字段,都能正确更新对应的state值,代码也更简洁。
内容的提问来源于stack exchange,提问作者T. Jefferds

