I have defined some react context for a shopping cart which I want to be able to access in every child component. I have also defined some methods (add to and remove from the shopping cart). I cannot get the addToCart function to work:
import React, { useContext, useState } from "react";
const ShoppingCartContext = React.createContext();
export function useShoppingCart() {
return useContext(ShoppingCartContext);
}
export function ShoppingCartProvider({ children }) {
const [shoppingCart, setShoppingCart] = useState([]);
function addToCart(item) {
setShoppingCart(shoppingCart.concat(item));
}
function removeFromCart(item) {
const index = shoppingCart.indexOf(item);
setShoppingCart(shoppingCart.splice(index, 1));
}
const value = { shoppingCart, setShoppingCart, addToCart, removeFromCart };
return (
<ShoppingCartContext.Provider value={value}>
{children}
</ShoppingCartContext.Provider>
);
}
In the file I want to access the shopping cart in, I am doing this:
const { shoppingCart, setShoppingCart, addToCart, removeFromCart } = useShoppingCart();
Then, in a useEffect(), I am doing this:
addToCart(["item"])
console.log(shoppingCart)
But it console.logs an empty array:
So, assuming that useEffect
is called after the initial render of your child component, the following happens
addToCart(["item"]) // context state is [], a rerender with the new state is scheduled
console.log(shoppingCart) // context state is [], an empty array is logged
After this, the state updates and your child component rerenders. If you move your console.log
out to the component body, you will see the change
const MyShoppingCartConsumingComponent = () => {
const { shoppingCart, setShoppingCart, addToCart, removeFromCart } = useShoppingCart();
React.useEffect(() => {
addToCart(['item'])
}, [])
console.log(shoppingCart)
return <p>yo!</p>
}
Something like this will be logged
[]
['item']