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?
>Solution :
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.
-
You initialize cart with an empty array using useState.
-
The CartPage component mounts, and at this point, cart is still an empty array because useEffect has not run yet.
-
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 ( // ... )}