Skip to content

React Router v4 Redux Middleware

John Henry Briggs edited this page Nov 9, 2018 · 2 revisions

You can also listen for a route change. React router dispatches an action type @@router/LOCATION_CHANGE every time the route changes. We are going to write a redux middleware to catch that. For more information about redux middleware visit the official docs https://redux.js.org/docs/advanced/Middleware.html

reactGAMiddlewares.js

import ReactGA from 'react-ga'

const options = {}

const trackPage = (page) => {
  ReactGA.set({
    page,
    ...options
  })
  ReactGA.pageview(page)
}

let currentPage = ''

export const googleAnalytics = store => next => action => {
  if (action.type === '@@router/LOCATION_CHANGE') {
    const nextPage = `${action.payload.location.pathname}${action.payload.location.search}`

    if (currentPage !== nextPage) {
      currentPage = nextPage
      trackPage(nextPage)
    }
  }

  return next(action)
}

Every time the page changes we use trackPage. Search queries are also checked.

Now let's add this middleware to redux and connect everything.

configureStore.js

import { applyMiddleware, combineReducers, compose, createStore } from 'redux'
import { routerMiddleware, routerReducer } from 'react-router-redux'
import * as reducers from '../reducers'
import { googleAnalytics } from './reactGAMiddlewares'

export default function (initialState, browserHistory) {
  const routermw = routerMiddleware(browserHistory)

  const store = createStore(
    createRootReducer(reducers),
    initialState,
    compose(
      applyMiddleware(routermw),
      applyMiddleware(googleAnalytics),
      window.devToolsExtension()
    )
  )

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      store.replaceReducer(createRootReducer(require('../reducers')))
    })
  }

  return store
}

Root.js

import React from 'react'
import { Provider } from 'react-redux'
import ReactGA from 'react-ga'

import configureStore from './configs/configureStore'
import createHistory from 'history/createBrowserHistory'

const history = createHistory()

ReactGA.initialize('UA-XXXXXX-X')

const store = configureStore({}, history)

export default () => (
  <Provider store={store}>
    // Your app goes here
  </Provider>
)
You can’t perform that action at this time.