How to Persist User Info Using Redux Persist with TypeScript
Tags: webdev, redux, reduxpersist, frontend
Published: 2024-05-13 09:39:03

As I was doing my React project, I was trying to persist user data using redux. And, here I am now to share with you how I solved my problem. Are we on the same page? Let's dive in!

Redux Persist is a library that enables seamless persisting and rehydrating of your Redux store state. By persisting your state, you ensure that user data remains intact even if the application is refreshed or closed temporarily. Installing Redux Persist is the first step towards achieving this persistence.

PS: Are you getting an error "A non-serializable value was detected in the state" using Redux-persist? Let's take of it as well.


### Step 1: Install Redux Persist Package

First things first, let's get Redux Persist up and running in your project. Install the package using npm or yarn:

```bash
npm install redux-persist
```

### Step 2: Setup Persist Config

In this step, you define a persist configuration object e.g. `authPersistConfig`. This object specifies how Redux Persist should handle the persistence of your Redux state. The key property uniquely identifies the slice of state you want to persist (in our case, "auth"). The storage property determines where the state will be stored (e.g., local storage). Additionally, you can specify any properties to [blacklist](https://www.npmjs.com/package/redux-persist#blacklist--whitelist) from being persisted (e.g., "somethingTemporary"). Refer back to their official docs for additional features.

```typescript
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import { authReducer } from './reducers/authReducer';

const authPersistConfig = {
  key: "auth",
  storage,
  blacklist: ["somethingTemporary"],
};

const persistedReducer = persistReducer(authPersistConfig, authReducer);
```

### Step 3: Configure Store Setup

Once you have your persist configuration set up, it's time to integrate it into your Redux store. You create a persisted reducer by passing your persist configuration and your reducer function to `persistReducer`. Then, you configure your Redux store using `configureStore` from Redux Toolkit, ensuring that the persisted reducer is included in the store configuration.

```typescript
import { configureStore } from '@reduxjs/toolkit';

export const Store = configureStore({
  reducer: {
    auth: persistedReducer,
  },
});
```

### Step 4: Debugging Error of Serialization

We are there almost! Now we have an error. 

> "A non-serializable value was detected in the state"

Serialization errors can occur when trying to persist certain types of data that cannot be serialized properly (e.g., functions or circular references). Redux Persist provides a [built-in solution for handling serialization errors](https://www.npmjs.com/package/redux-persist#transforms), but in this guide, we opt for a simpler approach using [Redux Toolkit Serializability Middleware](https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist). We configure the middleware to ignore specific actions that Redux Persist dispatches internally to serialize and deserialize state (FLUSH, REHYDRATE, etc.).

```typescript
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';
import { persistReducer, persistStore } from 'redux-persist';

export const Store = configureStore({
  reducer: {
    auth: persistedReducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});
```

### Step 5: Export Persistor

After configuring Redux store with Redux Persist, export a persistor object using `persistStore`. This persistor object is responsible for managing the persistence and rehydration of your Redux store state. It's typically used in conjunction with the PersistGate component in your application's entry point.

```typescript
import { persistStore } from 'redux-persist';

export const persistor = persistStore(Store);
```

### Step 6: Integrate with React

Finally, integrate Redux Persist with React by wrapping the application with the `PersistGate` component. The `PersistGate` ensures that your application waits for the persisted state to be loaded before rendering. This prevents any rendering inconsistencies that may occur while the state is being rehydrated.

```typescript
import { PersistGate } from 'redux-persist/integration/react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
);
```

Congratulations! You've successfully persisted user info using Redux Persist with TypeScript. Now sit back, relax, and enjoy the seamless user experience.

Leave a comment! Happy coding! 

*WebCraft With Hossain*