Persisting State in React App with Redux Persist
Redux Persist is a library used to save the Redux store’s state to persistent storage, such as local storage, and rehydrate it when the app loads. In this article, we make a simple counter application using React and Redux, demonstrating state persistence using Redux Persist. This project includes incrementing, decrementing, and resetting the counter value functionalities.
Working on Redux Persist Library
- Serialization: Whenever the Redux state changes, then Redux Persist intercepts your Redux store’s state and converts it into a format suitable for storage like JSON string.
- Store State : After serialization Redux Persist save this data to a specified storage (e.g., local storage).
- Rehydration: When the application loads, Redux Persist retrieves the persisted state from storage and injects it back into the Redux store before rendering the UI.
Approach
- Project Setup : Create a React Application and install required module like “redux-persist”.
- Set Up Redux Store with Persistence : Create an initial state and reducer for the counter, configure Redux Persist to use local storage, and create the Redux store with the persisted reducer and persistor.
- Counter Component : Create a Counter component and manage state with useSelector and useDispatch.
- Setup Redux Provider and PersistGate : Wrap the application in Provider to pass the store and PersistGate to ensure the persisted state is loaded before rendering the UI.
Steps to Create Application
Step 1: Create a React application using the following command.
npx create-react-app redux-persist-app
Step 2: After creating your project folder i.e. redux-persist-app, move to it using the following command.
cd redux-persist-app
Step 3 : Install required dependencies like redux-persist, and redux.
npm install redux react-redux redux-persist
Project Structure:
Updated dependencies in package.json file
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.1.2",
"redux": "^5.0.1",
"redux-persist": "^6.0.0",
},
Example: To demonstrate the implementation of the persisting state in a react-redux application by creating a simple counter app.
/* App.css */
button {
padding: 10px 20px;
background-color: rgba(204, 207, 205, 0.74);
margin: 10px 5px;
cursor: pointer;
}
button:hover {
background-color: rgba(9, 221, 9, 0.788);
}
#App {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
// store.js
import { createStore } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
// initial state
const initialState = {
value: 0,
};
// reducer
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, value: state.value + 1 };
case 'DECREMENT':
return { ...state, value: state.value - 1 };
case 'RESET':
return { ...state, value: 0 };
default:
return state;
}
};
// Persist configuration
const persistConfig = {
key: 'root',
storage,
};
// Create a persisted reducer
const persistedReducer = persistReducer(persistConfig, counterReducer);
// Create the Redux store
export const store = createStore(persistedReducer);
// Create a persistor
export const persistor = persistStore(store);
// App.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import './App.css'
const Counter = () => {
const count = useSelector((state) => state.value);
const dispatch = useDispatch();
return (
<div id='App'>
<h1><img src='https://media.w3wiki.net/gfg-gg-logo.svg' alt='gfg_logo' /> {" "} Counter: {count}</h1>
<div>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
</div>
</div>
);
};
export default Counter;
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store';
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<div className="App">
<App />
</div>
</PersistGate>
</Provider>
);
Output