Implementing React Redux Store With Persistence | by E.J. Ozyazgan | Apr, 2022

Centralized app state storage with persistence

Photo by Tim Evans on Unsplash

React Redux is a centralized state that allows you to decouple your state from individual components. This allows you to easily share and sync app state across components removing the need for unnecessary state chains.

In this article, I will cover the following to get Redux Store setup in any React App. The full repository for this project will be linked at the end of the article.

1. Creating the Redux Store
2. Modifying State with Reducers
3. Importing State and Reducers into Components
1. Function Component
2. Class Component
4. Adding Persistence

In order to add a Redux store to our app, we will first need to import React-Redux and the Redux Toolkit.

npm i react-redux @reduxjs/toolkit

We are now ready to set up our Redux store. The Redux store consists of two main components, the store itself and a data slice. The store is essentially a wrapper that handles injecting your data slice into your app. The data slice itself is where the state and reducers live.

Let us begin by creating the data slice. We use a method from Redux Toolkit, createSlice , in order to create the data slice. This method takes a JSON object containing our data slice name, initialState object, and reducers object.

When exporting our data slice we create two export statements. One for the reducer methods, DataSlice.actions and another default export for the data slice itself, DataSlice.reducer. This default export can be a bit confusing as it may seem as if it should only be the reducer methods. The default export is what is passed into our redux store wrapper.

React Data Slice

Now that we have our data slice we can create our store. The store is quite simple and is created by passing our data slice to the Redux Toolkit configureStore method. We then export our store to inject into our app later on.

Redux Store

Once our store is created we need to inject it into our app. We do this by wrapping our app in the Provider component from React-Redux. The Provider component takes in our store as a prop which allows us to import it into our components later on.

Inject Redux Store into App

Reducer methods consist of two parameters, state and actions. The state will always be the current state of the app and is automatically passed in. Actions is a JSON object that consists of two variables, type and payload . The type will be automatically set to the name of your data slice and reducer method, dataSlice/updateMessage in our example. The payload will consist of the data we pass into the reducer method from our components.

One key point to have in mind is the payload can only consist of one data point. Because of this if we need to pass multiple values ​​into our reducer method we will need to pass them to the payload using a JSON object.

When updating the state with redux we do not need to worry about mutating actions. Redux will automatically handle cloning and creating new objects in the state. Because of this, we are able to directly update the state within our reducers.

Now that we have our state and reducers all set up we can import them into our components. There are different ways to import state and reducers depending on the use of functional or class components. I will start by showing the use of hooks in functional components.

Functional Component

We will be using two hooks, useSelector and useDispatch , from React Redux to import our state and reducers into our function component. The useSelector hook allows us to select a certain state value from our data slice and save it as a local variable. The useDispatch hook gives us the ability to call reducers directly from within our component.

Import Redux State and Reducers into Function Component

Class Component

As for class components, we do not have access to hook so will use a different approach. This method of importing state and reducers also works in function components, however, I would highly recommend using the hook method instead.

For class components, we will utilize the connect method from React-Redux. This method is similar to the withStyles method commonly used to import styles. The connect method takes up to two parameters, one for state imports and another for reducers.

We will be importing both state and reducers using the mapStateToProps and mapDispatchToProps methods respectively. Both of these methods will return an object containing the state and reducers we need for our component. mapStateToProps has two parameters, state and ownProps . The state parameter is auto-populated and is the state object from our data slice and ownProps may be used to pass in local state properties. mapDispatchToProps has a single dispatch parameter that is auto-populated with the dispatch method similar to the useDispatch hook.

The connect method will then bind the state and reducers to our props allowing us to access them using this.props.<state or reducer> .

Import Redux State and Reducers into Class Component

In this section, I will cover how to add persistence to our Redux store in order to preserve data on page refresh. This is not necessary for Redux itself and is simply depending on your use case.

When adding persistence to our app we will first need to import an additional library, Redux Persist.

npm i redux-persist

Once we have Redux Persist installed we will need to make some changes to our Redux store and index.html files. Let us start with our Redux store.

Redux store with Redux Persist

At first glance, this looks quite different from our original store implementation. The primary changes are due to wrapping our data slice and store within the Redux Persist persistReducer and persistStore methods respectively.

The persistReducer method allows us to pass in our data slice as well as a persistence config. This config allows us to control how our store will be persisted. The main configuration to keep in mind is where the store will be persisted. In this example, we are using the browser’s local storage by using the following import import storage from ‘redux-persist/lib/storage' .

There are quite a few options for where to persist our store and they may all be found here.

In addition to configuring our data slice, we need to add some extra configuration to the store as well. This configuration is in the form of middleware. Persistence uses a serializable check to make sure the data we store is serializable. However, we do not want this check to be performed on certain actions performed by Redux Persist itself.

Once our middleware is set up we wrap our store in persistStore allowing it to be managed by Redux Persist. We will also need to export both our store as well as this new persistor returned from persistStore. Now that our store is reconfigured for persistence we need to inject our persistor into our app.

Inject Redux Persistor into App

In order to inject our persistor, we will use the PersitGate component provided by Redux Persist. This component will be a subcomponent of our Provider component and encompass the rest of our app.

We have successfully added a Redux store into our react app as well as added persistence to our store. As promised the repo for this project may be found below. There are two branches, main and react-persist . Main has the basic redux setup while react-persist has the persistence addition.

Leave a Comment