skip to Main Content

context/cart.jsx

import { useState, useContext, createContext, useEffect } from "react";

const CartContext = createContext()

const CartProvider = ({ children }) => {
    const [cart, setCart] = useState([])
    const existingCartItems = localStorage.getItem("cart");
    console.log(existingCartItems)

    useEffect(() => {
        setCart(JSON.parse(existingCartItems));
    }, [existingCartItems])

    console.log(cart)

    return (
        <CartContext.Provider value={[cart, setCart]}>
            {children}
        </CartContext.Provider>
    )
}

const useCart = () => useContext(CartContext)

export { useCart, CartProvider }

pages/CartPage.jsx

const CartPage = () => {
    const [cart, setCart] = useCart() <-- The value returning an empty array on first mount
}

I am trying to mount the value of cart with the local storage value instead of an empty array. What is the reason the cart returns an empty array on other component pages even I already used useEffect to set the value. How to have the cart returning the value in the local storage instead of returning an empty array on first mount?

3

Answers


  1. This will ensure that setCart is called on the initial mount with the parsed cart items even if existingCartItems is initially null or undefined. If existingCartItems is null, it will skip the setCart call because the if (parsedCart) check will fail. This way, you prevent setCart from being called with an empty array on the initial mount.

    Try this:

    useEffect(() => {
    const parsedCart = JSON.parse(existingCartItems);
    if (parsedCart) {
        setCart(parsedCart);
    } }, []);
    
    Login or Signup to reply.
  2. UseEffect will not call when changing local storage. So that’s why getting an empty array.

    Login or Signup to reply.
  3. Looks like encountering an issue with the initial state of your cart when your component mounts. The reason you’re seeing an empty array on the first mount is due to the sequence of operations and the asynchronous nature of useState and useEffect.

    1. You initialize cart with an empty array using useState.

    2. The CartPage component mounts, and at this point, cart is still an empty array because useEffect has not run yet.

    3. useEffect runs after the component mounts, but setting the state is asynchronous. So if you try to access cart immediately after the component mounts (such as in CartPage), it will still be an empty array.

       const CartProvider = ({ children }) => {
       const existingCartItems = localStorage.getItem("cart");
       const [cart, setCart] = useState(existingCartItems ? JSON.parse(existingCartItems) : []);
      
       useEffect(() => {
           if (existingCartItems) {
               setCart(JSON.parse(existingCartItems));
           }
       }, [existingCartItems])
      
       // ...
      
       return (
           // ...
       )
      

      }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search