Home > Software design >  How can i persist only a subset of state from React Redux?
How can i persist only a subset of state from React Redux?

Time:05-22

In my application i have two reducers that i want to persist only one of them which is cart.reducer , in cart reducer i have two values , one of them controls whether cart dropdown should be hidden or be shown to the user and the other one is the items that user added to the cart , when i try to persist this cart reducer both of this attributes persisted so when the user leaves the page with cart open , after re opening the page cart dropdown still open . this is the cart.reducer code :

import { CartActionTypes } from './cart.types';
import { addItemToCart , removeItemFromCart } from './cart.utils';

const INITIAL_STATE = {
   hidden: true,
   cartItems: []
};

const cartReducer = (state = INITIAL_STATE, action) => {
   switch(action.type) {
      case CartActionTypes.TOGGLE_CART_HIDDEN:
         return {
            ...state,
            hidden: !state.hidden
         };
      
      case CartActionTypes.ADD_ITEM:
         return {
            ...state,
            cartItems: addItemToCart(state.cartItems, action.payload)
         };

      case CartActionTypes.REMOVE_ITEM:
         return {
            ...state,
            cartItems: removeItemFromCart(state.cartItems, action.payload)
         };

      case CartActionTypes.CLEAR_ITEM_FROM_CART:
         return {
            ...state,
            cartItems: state.cartItems.filter(cartItem => cartItem.id != action.payload.id)
         };

      default:
         return state;
   }
}

export default cartReducer

root.reducer :


import userReducer from "./user/user.reducer";
import cartReducer from './cart/cart.reducer';

import { combineReducers  } from "redux";

// Redux Persist
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { createFilter } from 'redux-persist-transform-filter';



const saveSubsetFilter = createFilter('cart.reducer', ['cartItems'])

const persistConfig = {
   key: 'root',
   storage,
   whitelist: ['cart'],
   transforms: [saveSubsetFilter]
}



const rootReducer = combineReducers({
   user: userReducer,
   cart: cartReducer
})


export default persistReducer(persistConfig, rootReducer);

solved by redux-deep-persist thanks to Haken

...
**import { getPersistConfig } from 'redux-deep-persist';**

...

const persistConfig = **getPersistConfig**({
   key: 'root',
   storage,
   **whitelist: ['cart.cartItems'],**
   rootReducer,
})
...

CodePudding user response:

You can simplify your code by passing only the reducer cartReducer.

const persistConfig = {
   key: 'root',
   storage
}

persistReducer(persistConfig, cartReducer)`

CodePudding user response:

I think the options you have is to separate out the reducers for cart items and cart visibility if you want to use toggle logic with redux else the simplest and easiest way is to have a component level state to handle toggle cart hidden and only have cart items and persist cartReducer which will only persist cart items and the toggle would be handled locally.

import React from "react";

const Home = () => {
  const [toggle, settoggle] = useState(false);
  const handleToggle = () => settoggle((prevToggle) => !prevToggle);
  return (
    <div>
      {toggle && <div>{/* your cart component */}</div>}
      <Button onClick={handleToggle}>{toggle?'Hide':'Show'}</Button>
    </div>
  );
};

export default Home;

You can do something like this for local state manipulation and once the component unmounts or it will always have false as its initial state value preventing your cart to show.

  • Related