Making Redux State Persistent with Redux Toolkit and redux-persist
Effortlessly Persist Redux State Across Page Reloads
Introduction
Have you ever been in the middle of something important on a website, only to accidentally refresh the page and lose all your progress? It's frustrating, right? As developers, we aim to create smooth, user-friendly experiences, and one way to achieve that is by ensuring the app state persists across page reloads. Enter redux-persist
.
By integrating redux-persist
with Redux Toolkit, we can easily save our Redux state to local storage (or other storage options). This means users can pick up right where they left off, even after a page reload. Let's dive into how to set this up and make our applications more resilient.
Why Should We Use redux-persist?
State Persistence: Have you ever filled out a long form, accidentally refreshed the page, and had to start over?
redux-persist
helps avoid this by keeping your app's state intact across reloads.Enhanced User Experience: By retaining state, we can create a more seamless and enjoyable experience for users. No more lost data or interrupted workflows.
Reduced Server Load: By storing some state on the client side, we reduce the need for frequent server requests. This can improve performance and save on server costs.
Simple Integration: With Redux Toolkit, integrating
redux-persist
is straightforward and clean, making state management a breeze.
Step-by-Step Guide to Setting Up Redux with redux-persist
1. Define Your Slices
Slices in Redux Toolkit are a way to manage a single piece of your app's state. Think of it like a slice of the state pie. Here's an example of an authSlice
for handling authentication:
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
user: null,
token: null,
}
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
setUser(state, action) {
state.user = action.payload;
},
setToken(state, action) {
state.token = action.payload;
},
clearAuth(state) {
state.user = null;
state.token = null;
},
},
});
export const { setUser, setToken, clearAuth } = authSlice.actions;
export const authReducer = authSlice.reducer;
This slice includes the initial state and actions to update the state, such as setting and clearing the user.
2. Configure redux-persist
Next, we need to set up redux-persist
to save our authentication state. This involves creating a persist configuration and a persisted reducer.
import { configureStore } from '@reduxjs/toolkit';
import { authReducer } from './features/auth/authSlice';
import { baseApi } from './api/baseApi';
import storage from 'redux-persist/lib/storage';
import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';
// Define persist configuration for the auth slice
const authPersistConfig = {
key: 'auth',
storage: storage,
};
// Create a persisted reducer
const persistedReducer = persistReducer(authPersistConfig, authReducer);
// Configure the Redux store
export const store = configureStore({
reducer: {
[baseApi.reducerPath]: baseApi.reducer,
auth: persistedReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(baseApi.middleware),
});
// Create a persistor
export const persistor = persistStore(store);
// Infer types for the Redux state and dispatch
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Breaking Down the Key Concepts
Persist Configuration: This configuration tells
redux-persist
how and where to save the state. Thekey
specifies the key in storage, andstorage
specifies the storage engine (like local storage).Persisted Reducer: This is our original reducer wrapped in
persistReducer
, which handles the saving and loading of the state.Configure Store: Using Redux Toolkit's
configureStore
, we set up our store with the persisted reducer and apply necessary middleware. TheserializableCheck
option ensures we ignore certainredux-persist
actions during serialization checks to avoid errors.Persistor: The
persistStore
function creates a persistor linked to the Redux store, managing the persistence lifecycle, including saving and rehydrating the state.
Conclusion
By integrating Redux Toolkit with redux-persist
, we can effortlessly enhance our applications, ensuring a smoother and more reliable user experience. No more worries about losing state on page reloads! This setup not only simplifies state management but also makes our apps more robust and user-friendly. Give it a try and see how it transforms your development workflow.