基于React Boilerplate 4集成redux-persist时遇router reducer挂载错误
解决React Boilerplate 4集成redux-persist时的"Could not find router reducer in state tree"错误
我帮你分析下问题根源,再给出具体的修复步骤:
问题本质
你现在的代码直接把createReducer函数传给了persistReducer,但createReducer是React Boilerplate用来动态合并reducers的工具函数,不是最终包含所有reducer(包括connected-react-router的router reducer)的root reducer。redux-persist包装的对象不对,导致connected-react-router在状态树里找不到它依赖的router分支。
修复步骤
1. 修正configureStore.js中的reducer包装逻辑
我们需要先生成包含router reducer的完整root reducer,再用persistReducer包装它,同时推荐把路由状态排除在持久化之外(因为路由状态应该由浏览器URL控制,不需要本地存储):
import { createStore, applyMiddleware, compose } from 'redux'; import { persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web import { routerMiddleware, connectRouter } from 'connected-react-router'; import createReducer from './reducers'; // ...其他必要的导入 // 配置redux-persist,排除router状态 const persistConfig = { key: 'root', storage, blacklist: ['router'] }; export default function configureStore(initialState = {}, history) { const sagaMiddleware = createSagaMiddleware(reduxSagaMonitorOptions); const middlewares = [sagaMiddleware, routerMiddleware(history)]; const enhancers = [applyMiddleware(...middlewares)]; // 生成包含router reducer的完整root reducer const rootReducer = createReducer({ router: connectRouter(history) }); // 用persistReducer包装root reducer const persistedReducer = persistReducer(persistConfig, rootReducer); const store = createStore( persistedReducer, initialState, composeEnhancers(...enhancers), ); const persistor = persistStore(store); // ...保留原模板中的其他逻辑(比如注入reducers、运行saga等) return { store, persistor }; }
2. 确认createReducer函数能正确合并reducers
确保你的reducers.js中的createReducer函数可以正确合并传入的reducers,React Boilerplate默认的实现应该类似这样:
import { combineReducers } from 'redux'; export default function createReducer(injectedReducers = {}) { return combineReducers({ // 这里是你项目的默认reducers,比如auth、app等 ...injectedReducers, }); }
额外说明
添加blacklist: ['router']是因为路由状态不需要持久化:当用户刷新页面时,路由应该由浏览器的URL决定,而不是从localStorage恢复旧的路由状态,否则可能出现URL和页面路由不匹配的问题。
内容的提问来源于stack exchange,提问作者Jhony Moncada
相关产品推荐
相关产品推荐

