Homepage

Implementing React Redux in a Gatsby project

A guide to installing and setting up redux in a Gatsby frontend build

I recently undertook the task of moving an old React project into the Gatsby frontend framework. Mostly this was to take advantage of Gatsby serving React as static HTML files and resolving many of the SEO issues faced by pure React applications.

One of the issues I faced was exactly how to move across my existing Redux store into Gatsby. Gatsby uses it’s own pre-configured Webpack to create development and production builds and hooking up Redux into this process was far simpler than first thought… contrary to a lot of muddled guides online. Let’s run through the process in a few simple steps:

Step 1

First let’s install redux, react-redux and gatsby-plugin-react-redux (with a package manager of your choice - I’m using NPM):

npm i --save gatsby-plugin-react-redux react-redux redux

Step 2:

In our src folder, create a new folder called: state and inside the state folder create a folder named: reducers.

Inside reducers we will add any reducer.js files we want and combine them into one store.

Create a reducer test-reducer.js inside the reducers folder with contents:

const initialState = {
  aString:Test string’,
};

const testReducer = (state = initialState) => {
  // Create dispatch actions here
  return state;
};

export default testReducer;

Then create another file inside the reducers folder called index.js. This file will combine any and all reducers we add to the reducers folder like so:

import { combineReducers } from 'redux';

// Import other reducers
import testReducer from ‘./test-reducer';

// Combine all reducers
const rootReducer = combineReducers({
  testReducer,
});

export default rootReducer;

Next we need to create our redux store. In the state folder we created add a new file called: createStore.js - with the following contents:

import { createStore } from 'redux';
 
// Import the Root Reducer
import rootReducer from './reducers/index';

// preloadedState will be passed in by the plugin
export default preloadedState => {
  return createStore(rootReducer, preloadedState);
};

We now have an operational redux store that we can access in our build.

Step 3

In our gatsby-config.js file add the following plugin config. You will notice that we’re referencing the createStore.js that we created in Step 2:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-react-redux`,
      options: {
        // [required] - path to your createStore module
        pathToCreateStoreModule: './src/state/createStore',
        // [optional] - options passed to `serialize-javascript`
        // info: https://github.com/yahoo/serialize-javascript#options
        // will be merged with these defaults:
        serialize: {
          space: 0,
          // if `isJSON` is set to `false`, `eval` is used to deserialize redux state,
          // otherwise `JSON.parse` is used
          isJSON: true,
          unsafe: false,
          ignoreFunction: true,
        },
        // [optional] - if true will clean up after itself on the client, default:
        cleanupOnClient: true,
        // [optional] - name of key on `window` where serialized state will be stored, default:
        windowKey: '__PRELOADED_STATE__',
      },
    },
  ]
}

Unlike standard React builds we do not need to wrap our application/components with a react-redux { Provider }. Normally the Provider component gives our application/components access to our Redux store, but this is handled by our gatsby-plugin-react-redux plugin.

Step 4

We can now access our Redux store from any of our React components as per:

import { useSelector, useDispatch } from 'react-redux';

const TestComponent = () => {
  // React Redux hooks
  const dispatch = useDispatch();
  const query = useSelector((state) => state.testReducer);

  return (
    <p>{query.aString}</p>
  );
};

export default TestComponent;

Happy Gatsby-Reduxing!

What other people say

Other peoples’ opinions matter. I have worked with many people over the years and think it is important to share their experience of working with me.

  • React Development

    Tried and tested React application development. From super-fast single page applications to efficient large-scale corporate websites.

  • High-quality Templating

    Experienced approach to coding consistent and maintainable frontend templates and component libraries.

  • Accessibility Implementation

    Deep understanding of website accessibility, accessibility consultation, practical design, development, and testing experience.