How to Persist Redux State to LocalStorage in React

Redux persist package offers an easy way to save Redux store in local storage, session storage, and async storage.

When you refresh the browser the current state fades away, this can become cumbersome when you need to store the user state, and cart when building enterprise-level applications.

The Redux persist library helps you persist the state even after page refresh, not just that it also lets you customize the persisted state with its handy features.

In this step-by-step guide, you will find out how to use Redux Persist with Redux RTK in React to store the state in Local storage.

React Save State in LocalStorage with Redux Persist Tutorial

  • Step 1: Build React Project
  • Step 2: Install Redux Libraries
  • Step 3: Create Api Slice and Reducer
  • Step 4: Set Up Redux Store with Persist
  • Step 4: Show Redux Data in Components
  • Step 5: Register User Component
  • Step 6: Run Development Server

Build React Project

We have created the new React app; If you haven’t then go ahead and execute the following command.

npx create-react-app redux-persist-demo

Install Redux Libraries

For profound state management in React, we need a couple of packages that we can install using given commands.

npm install react-redux @reduxjs/toolkit redux-persist bootstrap

Create Api Slice and Reducer

In our app, we have to create the features folder with the apiSlice.js file. We will use this file to request the server for fetching the data.

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

export const apiSlice = createApi({
  reducerPath: "apiSlice",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://jsonplaceholder.typicode.com",
  }),
  endpoints: (builder) => ({
    getUsers: builder.query({
      query: () => "/users",
    }),
  }),
});

export const { useGetUsersQuery } = apiSlice;

Set Up Redux Store with Persist

In this step, you will have to create the store.js file in the app/ folder; In this file, we will set up the store and connect the redux store to redux persist.

import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import storage from "redux-persist/lib/storage";
import { combineReducers } from "@reduxjs/toolkit";
import { apiSlice } from "../features/apiSlice";

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

const persistConfig = {
  key: "root",
  storage: storage,
};

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;

Open the index.js file; wrap the App component with Provider and PersistGate modules to inject Redux persist in React app.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
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(
  <BrowserRouter>
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
  </BrowserRouter>
);

Show Redux Data in Components

Create and insert code into the components/Users.js file.

Fetch base query provides a hook that takes care of api handling smoothly by providing all the essential features such as loading, success, and error.

import React from "react";
import { useGetUsersQuery } from "../features/apiSlice";

function Users() {
  const { data, isLoading, isSuccess, isError, error } = useGetUsersQuery();

  let userContent;

  if (isLoading) {
    userContent = (
      <div className="d-flex justify-content-center w-100">
        <div className="spinner-border text-primary">
          <span className="visually-hidden">Loading...</span>
        </div>
      </div>
    );
  } else if (isSuccess) {
    userContent = data.map((res) => {
      return (
        <div className="col mb-2" key={res.id}>
          <div className="card">
            <div className="card-body">
              <h5 className="card-title">{res.username}</h5>
              <p className="card-text">{res.email}</p>
            </div>
          </div>
        </div>
      );
    });
  } else if (isError) {
    userContent = (
      <div className="alert alert-danger w-100 text-center">
        {error.status} {JSON.stringify(error)}
      </div>
    );
  }

  return <div className="col-12">{userContent}</div>;
}

export default Users;

Register User Component

Move to the App.js file, import the Users component in this file, adn define inside the App() function.

import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Users from "./components/Users";

function App() {
  return (
    <div className="container mt-4">
      <Users />
    </div>
  );
}

export default App;

Run Development Server

Run the react application server by using the npm start command and view your app on the browser with provided url.

npm start
http://localhost:3000

How to Persist Redux State to LocalStorage in React

Conclusion

We have created the React app that uses React Redux, RTK query, and Redux Persist for state management in React js environment. We have demystified the process of using Redux persist in Redux Toolkit to store the data in persistent storage.

This means our state will remain intact even after the page or browser refreesh.