reactjsreact-reduxlocal-storagereduceredux-reducers

How to store and get Cart Items to localstorage with Redux?


I'm using Redux toolkit and adding product items to the cart using redux in my eCommerce app, products are adding to the cart perfectly also I tried to store the added products to the localstorage which is also working fine but the thing is How can I use those items from localstorage to display the <CartItems> even after refreshing the page.

Here is my reducer:-

const productItemsSlice = createSlice({
    name: "product",
    initialState: {
        items: [],
        totalQuantity: 0,
        localStorageItems: [],
    },
    reducers: { 
        addProduct(state, action) {
            const newItem = action.payload;

            const existingItem = state.items.find((item) => item.id === newItem.id);

            state.totalQuantity++;

            if (!existingItem) {
                state.items.push({
                    id: newItem.id,
                    price: newItem.price,
                    quantity: 1,
                    totalPrice: newItem.price,
                    name: newItem.name,
                    image: newItem.image,
                    category: newItem.category,
                });
            } else {                
                existingItem.quantity = existingItem.quantity + 1;
                existingItem.totalPrice = existingItem.totalPrice + newItem.price;
            }

            // LOCAL STORAGE 
            localStorage.setItem("list", JSON.stringify(state.items));
            state.localStorageItems = JSON.parse(localStorage.getItem("list"));
        },
    },
});

And here I'm trying to access those setted cartItems to the localstorage:-

//<CartItems />  

//Here state.productItem is from configureStore reducer object:-
// const store = configureStore({
   // reducer: {
     //   productItem: productItemsSlice.reducer,
   // }
// })


const productItems = useSelector((state) => state.productItem.localStorageItems);
const items = productItems.map((el) => {
        return (
            <CartItems
                key={el.id}
                item={{
                    id: el.id,
                    name: el.name,
                    image: el.image,
                    price: el.price,
                    category: el.category,
                    totalPrice: el.totalPrice,
                    quantity: el.quantity,
                }}
            />
        );
    });

Please suggest me how can I achieve this, also if I remove items from cart.


Solution

  • Remove localStorageItems from initialState and add totalQuantity key for number of quantity to calculate how many items are added. Now we have to set localStorage for all these 3 initialState with different token key.

    Outside of slice function we parse Items:-

        const items =
            localStorage.getItem("cartList") !== null
                ? JSON.parse(localStorage.getItem("cartList"))
                : [];
        const totalAmount =
            localStorage.getItem("cartTotal") !== null
                ? JSON.parse(localStorage.getItem("cartTotal"))
                : 0;
        const totalQuantity =
            localStorage.getItem("cartQuantity") !== null
                ? JSON.parse(localStorage.getItem("cartQuantity"))
                : 0;
        
       // adding this function to prevent repear code 
        const setCartListFunc = (items, totalAmount, totalQuantity) => {
            localStorage.setItem("cartList", JSON.stringify(items));
            localStorage.setItem("cartTotal", JSON.stringify(totalAmount));
            localStorage.setItem("cartQuantity", JSON.stringify(totalQuantity));
        };
    

    This would be the initialState:-

       initialState: {
            items: items,
            totalQuantity: totalQuantity,
            totalAmount: totalAmount,
        },
    

    Now addProduct reducer should be like this to store the data to localStorage:-

    addProduct(state, action) {
        const newItem = action.payload;
    
        const existingItem = state.items.find((item) => item.id === newItem.id);
    
        state.totalQuantity++;
    
        if (!existingItem) {
            state.items.push({
                id: newItem.id,
                price: newItem.price,
                quantity: 1,
                totalPrice: newItem.price,
                name: newItem.name,
                image: newItem.image,
                category: newItem.category,
            });
        } else {                
            existingItem.quantity = existingItem.quantity + 1;
            existingItem.totalPrice = existingItem.totalPrice + newItem.price;
        }
    
     // added totalAmount to calculate number of items
        state.totalAmount = state.items.reduce(
            (total, items) => total + Number(items.price) * Number(items.quantity),
            0
        );
        
      // Using function for all initialState
        setCartListFunc(
            state.items.map((item) => item),
            state.totalAmount,
            state.totalQuantity
        );
    },