connected-react-router vs react-router vs react-router-redux vs redux-first-history
React Routing Libraries
connected-react-routerreact-routerreact-router-reduxredux-first-historySimilar Packages:

React Routing Libraries

These libraries facilitate routing in React applications, allowing developers to manage navigation and state in a way that integrates seamlessly with React's component-based architecture. They help in creating single-page applications (SPAs) by enabling dynamic routing, maintaining browser history, and ensuring that the UI reflects the current URL state. Each library offers unique features and approaches to routing, making them suitable for different use cases and preferences in state management.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
connected-react-router04,700444 kB176-MIT
react-router056,2524.14 MB156a month agoMIT
react-router-redux07,772-19 years agoMIT
redux-first-history045399.3 kB152 years agoMIT

Feature Comparison: connected-react-router vs react-router vs react-router-redux vs redux-first-history

State Management Integration

  • connected-react-router:

    This library integrates deeply with Redux, allowing you to keep your routing state in the Redux store. This means that any changes to the route can trigger Redux actions, making it easier to manage application state in a predictable manner.

  • react-router:

    React-router operates independently of Redux, focusing solely on routing. It provides a simple API for defining routes and managing navigation, making it ideal for applications that do not require complex state management.

  • react-router-redux:

    While it aimed to bridge React Router with Redux, it is now deprecated. It provided a way to sync routing state with Redux but is no longer recommended for new projects.

  • redux-first-history:

    This library allows you to create a history object that can be used with Redux, enabling you to manage navigation actions and state in a Redux-centric way. It provides a clear separation between routing and application state.

Flexibility and Complexity

  • connected-react-router:

    Offers flexibility by allowing developers to manage routing state alongside application state in Redux. This can add complexity but is beneficial for larger applications that require tight integration between routing and state management.

  • react-router:

    Highly flexible and easy to use, making it suitable for a wide range of applications. It allows developers to define nested routes and dynamic routing without the overhead of Redux.

  • react-router-redux:

    Provided a more complex solution for syncing routing with Redux, but its deprecation means it is no longer a viable option for new projects.

  • redux-first-history:

    Balances flexibility and complexity by allowing developers to manage routing in a Redux-first approach, making it suitable for applications that already use Redux.

Learning Curve

  • connected-react-router:

    Has a moderate learning curve due to its integration with Redux. Developers need to understand both Redux and React Router to use it effectively, which may take some time for beginners.

  • react-router:

    Generally considered easy to learn, especially for those familiar with React. Its API is straightforward, making it accessible for new developers.

  • react-router-redux:

    The learning curve was higher due to the need to understand both React Router and Redux. Its deprecation means it's no longer a recommended choice for new developers.

  • redux-first-history:

    Offers a moderate learning curve, especially for those familiar with Redux. It requires understanding how to manage history in a Redux-centric way.

Community and Support

  • connected-react-router:

    Has a growing community, especially among developers using Redux. However, it may not have as extensive support as more established libraries.

  • react-router:

    One of the most widely used routing libraries in the React ecosystem, with a large community and extensive documentation. It is well-supported and frequently updated.

  • react-router-redux:

    As a deprecated library, it no longer receives updates or community support, making it a poor choice for new projects.

  • redux-first-history:

    While it has a smaller community compared to react-router, it is gaining traction among Redux users looking for a history management solution.

Performance

  • connected-react-router:

    Performance is generally good, but it can be impacted by the complexity of the Redux state management. Proper optimization techniques in Redux can mitigate performance issues.

  • react-router:

    Offers excellent performance for most applications, with efficient route matching and rendering. It is optimized for single-page applications, ensuring fast navigation.

  • react-router-redux:

    Performance was dependent on both React Router and Redux, but its deprecation means it is no longer a consideration for new projects.

  • redux-first-history:

    Performance is generally good, but as with connected-react-router, it can be affected by how Redux is implemented in the application.

How to Choose: connected-react-router vs react-router vs react-router-redux vs redux-first-history

  • connected-react-router:

    Choose connected-react-router if you are using Redux for state management and want to synchronize your routing with the Redux store. It allows you to manage the routing state in Redux, making it easier to handle complex state interactions and side effects in your application.

  • react-router:

    Select react-router for a straightforward and flexible routing solution that is widely adopted in the React community. It is suitable for most applications, providing a robust API for defining routes and handling navigation without the need for Redux integration.

  • react-router-redux:

    Opt for react-router-redux if you need to connect your routing state to Redux but prefer a more integrated approach than connected-react-router. However, note that this package is now deprecated, and you may want to consider alternatives like connected-react-router instead.

  • redux-first-history:

    Use redux-first-history if you want to manage your routing in a Redux-first manner while maintaining a clear separation of concerns. It allows you to create a history object that integrates with Redux, enabling you to dispatch actions based on navigation events.

README for connected-react-router

Breaking change in v5.0.0! Please read How to migrate from v4 to v5/v6.

v6.0.0 requires React v16.4.0 and React Redux v6.0 / v7.0.

Connected React Router Build Status Open Source Helpers

A Redux binding for React Router v4 and v5

Main features

:sparkles: Synchronize router state with redux store through uni-directional flow (i.e. history -> store -> router -> components).

:gift: Supports React Router v4 and v5.

:sunny: Supports functional component hot reloading while preserving state (with react-hot-reload).

:tada: Dispatching of history methods (push, replace, go, goBack, goForward) works for both redux-thunk and redux-saga.

:snowman: Nested children can access routing state such as the current location directly with react-redux's connect.

:clock9: Supports time traveling in Redux DevTools.

:gem: Supports Immutable.js

:muscle: Supports TypeScript

Installation

Connected React Router requires React 16.4 and React Redux 6.0 or later.

npm install --save connected-react-router

Or

yarn add connected-react-router

Usage

Step 1

In your root reducer file,

  • Create a function that takes history as an argument and returns a root reducer.
  • Add router reducer into root reducer by passing history to connectRouter.
  • Note: The key MUST be router.
// reducers.js
import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'

const createRootReducer = (history) => combineReducers({
  router: connectRouter(history),
  ... // rest of your reducers
})
export default createRootReducer

Step 2

When creating a Redux store,

  • Create a history object.
  • Provide the created history to the root reducer creator.
  • Use routerMiddleware(history) if you want to dispatch history actions (e.g. to change URL with push('/path/to/somewhere')).
// configureStore.js
...
import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router'
import createRootReducer from './reducers'
...
export const history = createBrowserHistory()

export default function configureStore(preloadedState) {
  const store = createStore(
    createRootReducer(history), // root reducer with router state
    preloadedState,
    compose(
      applyMiddleware(
        routerMiddleware(history), // for dispatching history actions
        // ... other middlewares ...
      ),
    ),
  )

  return store
}

Step 3

  • Wrap your react-router v4/v5 routing with ConnectedRouter and pass the history object as a prop. Remember to delete any usage of BrowserRouter or NativeRouter as leaving this in will cause problems synchronising the state.
  • Place ConnectedRouter as a child of react-redux's Provider.
  • N.B. If doing server-side rendering, you should still use the StaticRouter from react-router on the server.
// index.js
...
import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4/v5
import { ConnectedRouter } from 'connected-react-router'
import configureStore, { history } from './configureStore'
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <> { /* your usual react-router v4/v5 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('react-root')
)

Note: the history object provided to router reducer, routerMiddleware, and ConnectedRouter component must be the same history object.

Now, it's ready to work!

Examples

See the examples folder

FAQ

Build

npm run build

Generated files will be in the lib folder.

Development

When testing the example apps with npm link or yarn link, you should explicitly provide the same Context to both Provider and ConnectedRouter to make sure that the ConnectedRouter doesn't pick up a different ReactReduxContext from a different node_modules folder.

In index.js.

...
import { Provider, ReactReduxContext } from 'react-redux'
...
      <Provider store={store} context={ReactReduxContext}>
        <App history={history} context={ReactReduxContext} />
      </Provider>
...

In App.js,

...
const App = ({ history, context }) => {
  return (
    <ConnectedRouter history={history} context={context}>
      { routes }
    </ConnectedRouter>
  )
}
...

Contributors

See Contributors and Acknowledge.

License

MIT License