How to Integrate Redux Persist to React 18 Redux Store

Last Updated on by in React JS

In this tutorial, we will step by step learn how to configure redux persist in the redux store using react-redux, redux toolkit, and redux persist libraries.

Redux persist is a powerful library that gives different storage options, such as local storage, session storage, and async storage.

The combineReducers function is used to group all the reducers and pass them to the persistReducer with persistConfig; in this guide, we will learn how to store api reducer state in local storage using redux persist.

React Redux Implement Redux Persist to Redux Store Example

  • Step 1: Install React Project
  • Step 2: Install Essential Packages
  • Step 3: Create Api with RTK Query
  • Step 4: Add Persist to Redux Store
  • Step 5: Show Persisted State
  • Step 6: Update Global Component
  • Step 7: Run Application

Install React Project

You have to firstly type the given command to create a new react applicaiton.

npx create-react-app react-redux-blog

We will keep this structure for our react redux project in this tutorial.

React Redux Persist Folder Structure Example

Install Essential Packages

Next, you need to go to the terminal screen, and here you have to add and execute the given command to install the essential packages in react.

npm install bootstrap react-redux @reduxjs/toolkit react-router-dom redux-persist --legacy-peer-deps

Create Api with RTK Query

In the features/ folder we have to create and add the given code to the apiSlice.js file. The response we get from this api will be made persisted state.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const apiSlice = createApi({
  reducerPath: 'apiProductSlice',
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://fakestoreapi.com',
  }),
  tagTypes: ['Product'],
  endpoints: (builder) => ({
    getProducts: builder.query({
      query: () => '/products',
      providesTags: ['Product'],
    }),
  }),
})

export const { useGetProductsQuery } = apiSlice

Add Persist to Redux Store

A redux store is a centrally distributed state; this file handles the store configuration where we pass the multiple reducers. Here we will also use the redux persist methods and combine reducers to set the persisted state collectively.

Create the app/ folder and store.js file inside of it, you have to add the following code to the file.

import { configureStore } from '@reduxjs/toolkit'
import { setupListeners } from '@reduxjs/toolkit/query'

import { combineReducers } from '@reduxjs/toolkit'
import { apiSlice } from '../features/apiSlice'

import storage from 'redux-persist/lib/storage'

import {
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist'

const persistConfig = {
  key: 'root',
  storage: storage,
  blacklist: ['apiProductSlice'],
}

export const rootReducers = combineReducers({
  [apiSlice.reducerPath]: apiSlice.reducer,
})

const persistedReducer = persistReducer(persistConfig, rootReducers)

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(apiSlice.middleware),
})

setupListeners(store.dispatch)

export default store

Wrap the App component using the Provider and PersistGate properties, and place the code in the index.js file.

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

import { Provider } from 'react-redux'
import { persistStore } from 'redux-persist'
import { PersistGate } from 'redux-persist/integration/react'


import store from './app/store'

let persistor = persistStore(store)

const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(
  <Provider store={store}>
    <PersistGate persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
)

Show Persisted State

You have to create the src/components/cart/Products.js file, here in this file you can use the useGetProductsQuery, useDispatch hooks to show the persisted state in React app.

import React, { useEffect } from 'react'
import { useGetProductsQuery } from '../../features/apiSlice'
import { useDispatch } from 'react-redux'

function Products() {
  const dispatch = useDispatch()

  const {
    data: products,
    isLoading: isProductLoading,
    isSuccess: isProductSuccess,
    isError: isProductError,
    error: prouctError,
  } = useGetProductsQuery({ refetchOnMountOrArgChange: true })

  useEffect(() => {}, [dispatch])

  let getData

  if (isProductLoading) {
    getData = (
      <div className="d-flex justify-content-center w-100">
        <div className="spinner-border text-primary" role="status">
          <span className="visually-hidden">Loading...</span>
        </div>
      </div>
    )
  } else if (isProductSuccess) {
    getData = products.map((item) => {
      return (
        <div className="col" key={item.id}>
          <div className="card h-100 product-card">
            <div className="img-grid mb-3">
              <img src={item.image} className="card-img-top" alt={item.title} />
            </div>
            <div className="card-body">
              <h5 className="card-title">${item.price}</h5>
              <p className="card-text">
                {item.description.substring(0, 50)}...
              </p>
              <button className="btn btn-outline-danger me-2">Buy now</button>
              <button className="btn btn-outline-primary">Add to cart</button>
            </div>
          </div>
        </div>
      )
    })
  } else if (isProductError) {
    getData = (
      <div className="alert alert-danger w-100 text-center" role="alert">
        {prouctError.status} {JSON.stringify(prouctError)}
      </div>
    )
  }

  return (
    <div>
      <div className="row row-cols-1 row-cols-md-3 row-cols-sm-2 g-4">
        <h2 className="mb-4">How to Use Redux Persist with Redux Toolkit</h2>
        {getData}
      </div>
    </div>
  )
}

export default Products

Update Global Component

To show the persisted data in React view, we have to import and register the Products component to the App.js file.

import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import './App.css'
import Products from './components/products/Products'

function App() {
  return (
    <div className="container py-3">
      <Products />
    </div>
  )
}

export default App

Run Application

In the last step, we only have to start the react app; after you execute the given command, your app will be served on the browser with the given URL.

npm start
http://localhost:3000

You can check the product data in local storage on the browser console.

How to Integrate Redux Persist to React Redux Store

Conclusion

Data is retrieved using the REST API in an application; based on our requirement; we show data through views. However, we can lose the data after we refresh the browser; here comes the redux middleware handy.

This guide taught us how to store redux state in local storage using the redux persist module.