使用combineReducers后React/Redux应用崩溃,无法获取状态
兄弟,我太懂你这种合并Reducer后突然崩掉的崩溃感了!其实核心问题就是合并Reducer后,你的Redux状态结构完全变了,而你的组件还在用旧的路径去取数据,自然就拿到undefined,然后map的时候就报错了。
为什么会这样?
当你只用单个TodoApp reducer时,Redux的根状态就是TodoApp reducer返回的对象(比如可能是{ todos: [], filter: 'all' }这种结构)。但用combineReducers合并后,根状态会变成一个由各个reducer命名作为key的对象,比如你如果是这么合并的:
import { combineReducers } from 'redux'; import TodoApp from './TodoApp'; import EditButton from './EditButton'; const rootReducer = combineReducers({ todoApp: TodoApp, // 这里的key是你给这个reducer起的名字 editButton: EditButton });
那你的根状态结构就变成了:
{ todoApp: { /* 原来TodoApp reducer返回的状态 */ }, editButton: { /* EditButton reducer返回的状态 */ } }
你需要改什么?
检查组件的
mapStateToProps路径
之前你可能是这么写的(单个reducer时没问题):const mapStateToProps = (state) => { return { todos: state.todos // 现在state.todos不存在了! }; };现在必须加上你给
TodoAppreducer起的key,改成:const mapStateToProps = (state) => { return { todos: state.todoApp.todos // 路径要对应合并后的结构 }; };(如果合并时你给的key不是
todoApp,比如是todoReducer,那路径就是state.todoReducer.todos,别写错!)快速调试确认状态结构
实在不确定的话,直接在mapStateToProps里打个console.log(state),启动应用后看控制台的状态结构,就能清楚看到你的todos到底在哪个层级下。确认App组件本身的状态访问是否正确
你说App组件能正常操作状态,大概率是因为App里已经调整了路径(比如用了state.todoApp),但嵌套的组件/容器还没同步修改,这才导致只有嵌套组件报错。
额外提醒
如果你的EditButton reducer也需要在组件里访问,同样要对应到state.editButton.xxx的路径,别再用旧的直接取state.xxx的方式了。
内容的提问来源于stack exchange,提问作者Max Wolfen

