如何扩展react-router-redux(5.x.x)的router reducer?
扩展react-router-redux 5.x的Router Reducer来存储额外路由信息
完全可以实现!react-router-redux 5.x的routerReducer本质是一个纯函数,我们可以通过包装原reducer的方式,在保留其核心路由管理功能的同时,在同一个router状态节点下添加自定义的路由相关信息(比如访问历史、初始参数),不需要单独创建新的reducer。
具体实现步骤
1. 创建扩展的Router Reducer
我们需要写一个自定义reducer,它会先调用原routerReducer处理路由相关的action,再叠加我们的自定义逻辑(比如记录访问历史、保存初始参数):
import { routerReducer, LOCATION_CHANGE } from 'react-router-redux'; // 初始化状态:包含原router的初始状态 + 自定义字段 const initialState = { ...routerReducer(undefined, {}), // 初始化原生路由状态 visitedRoutes: [], // 存储所有访问过的路由 initialParams: null // 存储首次进入站点的参数 }; const extendedRouterReducer = (state = initialState, action) => { // 先让原生routerReducer处理action,确保核心路由状态正确更新 const updatedRouterState = routerReducer(state, action); // 监听路由变化的action(LOCATION_CHANGE是react-router-redux内部派发的) if (action.type === LOCATION_CHANGE) { const { payload } = action; // 避免重复记录相同路由(可选,根据你的需求调整逻辑) const lastVisitedRoute = state.visitedRoutes[state.visitedRoutes.length - 1]; const shouldAddRoute = !lastVisitedRoute || lastVisitedRoute.pathname !== payload.pathname; return { ...updatedRouterState, // 添加新路由到历史记录(如果需要去重的话用上面的判断) visitedRoutes: shouldAddRoute ? [...state.visitedRoutes, payload] : state.visitedRoutes, // 首次进入时保存参数 initialParams: state.initialParams || payload.params }; } // 处理其他自定义action(比如手动清除访问历史) if (action.type === 'CLEAR_VISITED_ROUTES') { return { ...updatedRouterState, visitedRoutes: [], initialParams: state.initialParams }; } // 其他情况返回合并后的状态 return { ...updatedRouterState, visitedRoutes: state.visitedRoutes, initialParams: state.initialParams }; };
2. 在Store中使用扩展后的Reducer
把原来配置中的router: routerReducer替换成我们的扩展reducer即可:
import { createStore, combineReducers, applyMiddleware } from 'redux'; import { routerMiddleware } from 'react-router-redux'; import { browserHistory } from 'react-router'; import extendedRouterReducer from './path-to-your-extended-reducer'; // 创建路由中间件 const routingMiddleware = routerMiddleware(browserHistory); // 根reducer const rootReducer = combineReducers({ router: extendedRouterReducer, // 替换原生router reducer // 你的其他reducers... }); // 创建store const store = createStore( rootReducer, applyMiddleware(routingMiddleware) );
关键说明
- 这种方式完全保留了
routerReducer的原生功能(比如同步路由状态到store、处理路由跳转action等),只是在其基础上扩展了状态字段。 LOCATION_CHANGE是react-router-redux内部在路由变化时自动派发的action类型,我们通过监听它来实现路由历史的记录。- 如果需要添加更多自定义逻辑(比如记录路由停留时间),只需要在
LOCATION_CHANGE的case里扩展即可。
相关API参考
react-router-redux 5.x的官方文档中虽然没有专门的"扩展reducer"章节,但它的核心设计允许开发者通过包装reducer的方式扩展状态——因为routerReducer本身就是一个符合Redux规范的纯函数,遵循Reducer的组合原则。你可以在其官方文档的"Reducer"部分找到关于routerReducer的基础说明,理解它的输入输出逻辑后,就能轻松进行扩展。
内容的提问来源于stack exchange,提问作者Paul T
相关产品推荐
相关产品推荐

