React Router Redux Sync
react-router-redux, specifically version 4.0.8, provided "ruthlessly simple bindings" to keep React Router (versions 2.x and 3.x) and Redux in sync. Its primary purpose was to store React Router's location state within the Redux store, enabling features like time-travel debugging with Redux DevTools. It offered middleware to dispatch navigation actions and a reducer to manage router state. The library itself was noted as 'beta software' in its README. While `react-router-redux` version 5.x was intended for React Router 4.x, the repository for this project has been archived since October 26, 2018, rendering it abandoned. Modern React applications typically use `@reduxjs/toolkit` and `react-router-dom` directly, often with `connected-react-router` (a spiritual successor) or `redux-first-history` for similar state synchronization needs, rather than this deprecated package.
Common errors
-
Error: Calling routerReducer() with no args crashes.
cause An early bug in `routerReducer` in versions 4.0.0 and 4.0.1 where it was not robust to being called without arguments.fixUpgrade to `react-router-redux` version 4.0.2 or later to resolve this issue. -
Blank page on initial route redirect
cause An issue in early 4.0.0-beta/rc releases where an initial route redirect could lead to a blank page.fixEnsure you are using at least `react-router-redux` version 4.0.0-rc.2 or later, which included a fix for this bug. -
TypeError: createHistory is not a function or history/createBrowserHistory not found
cause Incorrect import or version mismatch of the `history` package. `createBrowserHistory` was moved to a sub-path in newer `history` versions.fixFor `react-router-redux` v4.x, ensure you have `history` installed (e.g., `npm install --save history`). The usage example imports `createHistory from 'history/createBrowserHistory'`, which is for `history` v4.x. If using an older `history` version, `createBrowserHistory` might be a direct export from 'history'.
Warnings
- breaking Version 4.0.0 introduced significant breaking changes. Action creators and middleware were separated from the history syncing function, and the use of action creators for navigation became largely obsoleted by React Router's new history singletons (React Router v2.0+). The library's scope was reduced to primarily focus on syncing history state to the Redux store for purposes like time travel.
- deprecated The `reactjs/react-router-redux` GitHub repository was archived on October 26, 2018, and is now read-only. This library is no longer actively maintained.
- gotcha This version (4.x) of `react-router-redux` is primarily intended for use with `react-router` versions 2.x and 3.x. The README, however, mentions 'react-router-redux 5.x for use with react-router 4.x' which can lead to confusion if you are using a newer React Router version with `react-router-redux` 4.x.
- gotcha The library explicitly states it's 'beta software' in its README, indicating potential instability, unaddressed bugs, or API changes, even at its final release.
- gotcha Accessing router state directly from the Redux store is discouraged. React Router operates asynchronously, and the component tree may not be updated in sync with the Redux state.
Install
-
npm install react-router-redux -
yarn add react-router-redux -
pnpm add react-router-redux
Imports
- ConnectedRouter
import ConnectedRouter from 'react-router-redux'
import { ConnectedRouter } from 'react-router-redux' - routerReducer
const routerReducer = require('react-router-redux').routerReducerimport { routerReducer } from 'react-router-redux' - routerMiddleware
import routerMiddleware from 'react-router-redux/middleware'
import { routerMiddleware } from 'react-router-redux' - push
import { browserHistory, push } from 'react-router'import { push } from 'react-router-redux'
Quickstart
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import createHistory from 'history/createBrowserHistory';
import { Route } from 'react-router';
import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux';
// Placeholder for your application's reducers
const reducers = (state = {}, action) => state;
// Placeholder components
const Home = () => <div>Home</div>;
const About = () => <div>About</div>;
const Topics = () => <div>Topics</div>;
// Create a history of your choosing (e.g., browser history)
const history = createHistory();
// Build the middleware for intercepting and dispatching navigation actions
const middleware = routerMiddleware(history);
// Add the routerReducer to your store on the `router` key
// Also apply our middleware for navigating
const store = createStore(
combineReducers({
...reducers,
router: routerReducer
}),
applyMiddleware(middleware)
);
// Example of dispatching a navigation action (can be done from anywhere)
// setTimeout(() => {
// store.dispatch(push('/about'));
// }, 2000);
ReactDOM.render(
<Provider store={store}>
{ /* ConnectedRouter will use the store from Provider automatically */ }
<ConnectedRouter history={history}>
<div>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
);