Setting localStorage with cart Products

Viewed 377

I am implementing a e-commerce project in which i want store cartItems in local storage in react so it does not disappear after refresh. Cart Items are set to local storage successfully but when i refresh it again set to empty array. here is the code:

 useEffect(() => {
    localStorage.setItem("cartItems", JSON.stringify(cart.cartItems));
}, [cart.cartItems])
useEffect(() => {
  let cartProducts = JSON.parse(localStorage.getItem("cartItems"));
  if(cartProducts){
    setCart({...cart,cartItems:[...cartProducts]});
  }
}, []) 


here is the state:
const [cart, setCart] = useState({
        cartItems: []
    });
2 Answers

On Each refresh of page, due to this stateAssignment

const [cart, setCart] = useState({cartItems: []}); This useEffect is executed.

useEffect(() => {
    localStorage.setItem("cartItems", JSON.stringify(cart.cartItems));
}, [cart.cartItems])

And at that time cart.cartItems is []. Hence it is set to [].

You need to make sure that this useEffect should only run when there is a user-initiated change in cart.cartItems.

Issue

When both effects run when the component mounts, the initial render uses the empty array ([]) state to update localStorage. The second effect picks up the newly set empty array and reads it back into state.

Solution

Use an initializer function for your state. Then the effect can persist cart to localStorage upon updates as usual.

const initializeState = () => ({
  cartItems: JSON.parse(localStorage.getItem("cartItems")) || [],
});

const [cart, setCart] = useState(initializeState());

useEffect(() => {
  localStorage.setItem("cartItems", JSON.stringify(cart.cartItems));
}, [cart.cartItems]);
Related