In short
Refresh the page and your Redux store starts empty again. Redux Persist saves the parts of the store you choose and loads them back when the app starts.
A library that automatically saves your Redux store to storage (like localStorage) and rehydrates it on page load, so state survives refreshes.

Think of it like this
A photo of the whiteboard
Before class ends and the board gets wiped, someone clicks a photo. Next day the teacher looks at the photo and rewrites the board. Redux Persist takes that photo of your store into localStorage, then restores it when the app reloads.
Watch it happen
Save, refresh, restore
cart/addItem
1/5You add an item, and the action reaches the persisted root reducer.
The big ideas
What you need to know
persistReducer wraps a reducer
It saves that reducer's state to storage whenever it changes.
Rehydration on startup
persistStore reads the saved state back and dispatches a REHYDRATE action to put it in the store.
PersistGate waits
Wrap your UI in PersistGate so it renders only after the saved state has been restored.
whitelist and blacklist
Save only what makes sense, like the cart and theme, and skip things like loading flags.
See it in code
Walk through the code
1import { combineReducers, configureStore } from "@reduxjs/toolkit";2import { persistReducer, persistStore, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from "redux-persist";3import storage from "redux-persist/lib/storage"; // localStorage4import { cartReducer, uiReducer } from "./slices";5 6const root = combineReducers({ cart: cartReducer, ui: uiReducer });7const persisted = persistReducer({ key: "root", storage, whitelist: ["cart"] }, root);8 9export const store = configureStore({10 reducer: persisted,11 middleware: (getDefault) =>12 getDefault({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER] } }),13});14export const persistor = persistStore(store);15 16// <PersistGate loading={null} persistor={persistor}><App /></PersistGate>1/4Combine the slices into one root reducer.
Only cart is saved. ignoredActions stops RTK's serializability check from warning about redux-persist's own actions. PersistGate comes from redux-persist/integration/react.
Save yourself the pain
Common mistakes
Oops
Persisting the whole store, loading flags and errors included.
Do this instead
Use whitelist so only lasting data is saved. A stale loading: true after a refresh is a classic bug.
Oops
Changing the shape of persisted state and shipping it as is.
Do this instead
Old saved data won't match anymore. Bump the version in the config and add a migrate function.
Oops
Persisting auth tokens to localStorage.
Do this instead
Any script on the page can read localStorage. Keep tokens in HttpOnly cookies instead.
Your mission
Make the cart survive a refresh
Quick check
Your persist config has whitelist: ["cart"]. After a refresh, what comes back?
Go deeper
- 1Add Redux Persist to a Redux Toolkit store and confirm state survives a refresh.
- 2Learn `whitelist`/`blacklist` config to persist only specific slices.
- 3Understand the rehydration flow and why there's often a brief 'loading' state on startup.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.