Setting up Redux with Create React App
redux makes managing react state efficient and fun
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;
Wrapping App with Provider
Now we want to wrap our apps root container with our redux store.
ReactDOM.render(<Provider store={store}>
<Router history={history}>
<Switch>
<Route path="/" />
</Switch>
</Router>
</Provider>, document.getElementById("root"));
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);