Setting up Redux with GatsbyJS V2

redux makes managing react state efficient and fun

Fri, 02 Nov 2018

Redux allows us to manage state across multiple components without having to pass props to between components. If you have a simple application, I wouldn’t bother using Redux unless you have a specific use for it. For example, in this tutorial I use redux to redirect the user back to the link where they started their authentication from.

Setup

npm install react-redux redux

yarn add react-redux redux

Actions

For this example we are just going to add only one action to our actions file. Create a new file for your actions named index.js located in src/actions

export const setCallbackLink = callbackLink => ({ type: 'SET_CALLBACK_LINK', callbackLink });

Store

This file will be named createStore.js located in src/state

import { createStore as reduxCreateStore } from 'redux';

const reducer = (state, action) => {

  if (action.type === 'SET_CALLBACK_LINK') {
    return Object.assign({}, state, { callbackLink: action.callbackLink });
  }

  return state;
};

const initialState = {
  callbackLink: '/',
};

const createStore = () => reduxCreateStore(reducer, initialState)

export default createStore;

Wrap with Provider

Create a new file at the root of your project named wrap-with-provider.js. This file will be imported in our gatsby-browser and gatsby-ssr and wrapped around our entire application allowing any component to access our store.

import React from 'react';
import { Provider } from 'react-redux';
import createStore from './src/state/createStore';

const { store } = createStore();

export default ({ element }) => (
  <Provider store={store}>
      {element}
  </Provider>
);

Gatsby SSR and Browser

Our Gatsby SSR and Browser files will be identical. Create a gatsby-ssr.js and gatsby-browser.js file at the root of your projects directory.

import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider

Accessing Store in Client

You can wrap any component with a Redux connect in order to be able to access your store from anywhere. In this example we inject the callbackLink using mapDispatchToProps. Once we do that we are able to access that variable inside of props.

import React, { Component } from 'react';
import loading from 'assets/images/loading.svg';
import { navigate } from 'gatsby';
import { handleAuthentication } from 'auth/Auth';
import { connect } from 'react-redux';
import { setCallbackLink } from '../actions';

const mapStateToProps = ({ callbackLink }) => ({ callbackLink });

const mapDispatchToProps = dispatch => ({
  setCallbackLink: callbackLink => dispatch(setCallbackLink(callbackLink)),
});

class Callback extends Component {
  componentDidMount() {
    const { callbackLink } = this.props;
    handleAuthentication();
    setTimeout(() => {
      if (callbackLink === '/') {
        navigate('/search');
      } else {
        navigate(callbackLink);
      }
    }, 1500);
  }

  render() {
    return (
      <div style={{
        position: 'absolute',
        display: 'flex',
        justifyContent: 'center',
        height: '98vh',
        width: '98vw',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        backgroundColor: 'white',
      }}
      >
        <img src={loading} alt="loading" />
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Callback);
Loading...
Edward Beazer

Edward Beazer - I just like to build shit. Sometimes I get stuck for hours, even days while trying to figure out how to solve an issue or implement a new feature. Hope my tips and tutorials can save you some time.