December 04, 2023
Simplified Global State Management and API Requests in React Typescript: Enhancing User Experience with redux-persist (Part Two)
Introduction
In our previous series, https://onlycoders.net/article/90/simplified-global-state-management-and-api-requests-in-react-typescript-implementing-redux-toolkit-rtk-and-rtk-query-part-one-90, we explored the implementation of Redux for global state management in React. However, we encountered a drawback: the absence of data persistence on page or hard refresh. To address this and ensure a seamless user experience, we'll dive into implementing Redux Persist using the redux-persist
package, continuing from where we left off in the previous series.
Implementation Steps
- Installation of Redux Persist
Begin by installing the 'redux-persist' package:
npm i redux-persist
Start the application:
npm run dev
2. Adapting the Redux Store
In the src/app/store.ts
directory, modify the Redux store to incorporate redux-persist
.
Snippet:
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import storage from "redux-persist/lib/storage";
import {
persistReducer,
PersistConfig,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from "redux-persist";
import counterReducer from "../pages/counter/counterSlice";
// Persist configuration
const perisistConfig: PersistConfig<RootState> = {
key: "root",
version: 1,
storage,
/**
* https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist
*
* It is also strongly recommended to blacklist any api(s) that you have configured with RTK Query. If the api slice reducer is not blacklisted, the api cache will be automatically persisted and restored which could leave you with phantom subscriptions from components that do not exist any more.
*/
// blacklist: [pokemonApi.reducerPath],
};
const rootReducer = combineReducers({
// Key should match name of slice
counter: counterReducer,
});
// Persist the reducers
const persistedReducer = persistReducer(perisistConfig, rootReducer);
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
});
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof rootReducer>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;
Here, we configure redux-persist
using persistReducer
and define perisistConfig
. This configuration includes setting a key
for storing data in the local storage and optionally blacklisting specific reducers from being persisted. Blacklisting ensures that certain data, such as API caches from RTK Query, isn't persisted unnecessarily. This is recommended by redux because If the api slice
reducer is not blacklisted, the API cache will be automatically persisted and restored which could leave you with outdated subscriptions from components that do not exist anymore.
3. Combining Reducers
Employ combineReducers
to structure a cleaner object for the persistReducer
definition, enhancing readability and manageability.
4. Integration of Redux Persist in the Application
Integrate redux-persist
into the root of your React application and wrap the app with PersistGate
to manage the persistence process.
Snippets:
import ReactDOM from "react-dom/client";
import { persistStore } from "redux-persist";
import { PersistGate } from "redux-persist/integration/react";
import App from "./App.tsx";
import { store } from "./app/store";
import "./index.css";
const persistor = persistStore(store);
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>
</React.StrictMode>
);
Here, we import persistStore
from redux-persist
and use PersistGate
to wrap the App
component within Provider
, ensuring seamless persistence of the Redux store across sessions.
Conclusion
By implementing redux-persist
, we've enhanced our Redux-powered React application, ensuring data persistence and providing a smoother user experience. Stay tuned for further enhancements in the next series!
486 views