React Router Dom v4 with Redux

React Router handles things differently in the new version. If you want to push routes using redux, you will need browserHistory or hashHistory. In react router v4, now there's no importable history object. But you can still create history manually using 'history' library.

Below is simply how I create history to pass onto redux middleware so I can dispatch pushing of a new route.

I use below libraries for

npm install --save react-router-dom
npm install --save react-router-redux
npm install --save history

I'm using HashRouter so I imported createHashHistory from the history library to create the history to pass into my middleware. If you're using MemoryRouter or BrowserRouter you should use the relevant function to create the history.

Then I create a middleware using routerMiddleware of the react-router-redux library. And along with my other middlewares (thunk etc.) and my reducers I create the store.

import { createStore, applyMiddleware, compose } from 'redux';
import { rootReducer } from 'redux/rootReducer';
import thunk from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux';
import { createHashHistory } from 'history';


const reduxRouterMiddleware = routerMiddleware(createHashHistory());
const middleware = [thunk, reduxRouterMiddleware];

export const store = createStore(
  rootReducer,
  compose(applyMiddleware(...middleware), window.devToolsExtension ? window.devToolsExtension() : f => f)
);

Then from your thunks or reducers you can dispatch push commands to the router. So you don't need to create extra reducers and connect them to a React component and do potentially buggy and not-so-elegant ways.

import { push } from 'react-router-redux';

export const signUp = signupData => {
  return (dispatch, getState) => {
    fetch('/myapi').then(
      response => {
        if (response.statusCode = 200)
          dispatch(push('/main'));
        else
          dispatch(push('/forbidden'))
      }
    );
  }
}