On, clicking a button to add an item to an array initialised as cart, the added item immediately appears in the cart array however, when I console.log the array, the item added does not get shown until after the next click. In that the first time the add button is clicked and the cart array console.logged; an empty array is returned. On the second click, the cart array is returned with only one item, the one supposedly added on the first click and so on, yet when I call a map method on the cart array, all the added elements are present. Why does it seem as though there is a delay?
const [cart, setCart] = useState([]); const addItem = (prod, index) => { setCart([...cart, prod]); console.log(cart);//seems to have a delay, one less item featured each click }; return ( <> <div className="cartItems"> {cart.map((prod, index) => { return ( <div key={prod.id} className=""> <h2 className="itemTitle">{prod.name}</h2> </div> ); })} </div> <div className="itemsContainer"> {products.map((prod, index) => { return ( <div key={prod.id} className="itemContainer"> <img src={prod.src} alt={prod.name} className="itemImage" /> <h2 className="itemTitle">{prod.name}</h2> <span className="itemPrice">{prod.priceN}</span> <button className="itemButton" onClick={() => { addItem(prod, index); }} > Order </button> </div> ); })} </div> </> );
Advertisement
Answer
You can’t get the correct value from state variable after setting it up.
You updated your state value cart
by setCart([...cart, prod]);
.
Then you tried to print cart
at the next line.
const addItem = (prod, index) => { setCart([...cart, prod]); console.log(cart);//seems to have a delay, one less item featured each click };
But it doesn’t work. Because setState works asynchronously in React.
Here is the statement in Reactjs official document.
State Updates May Be Asynchronous
React may batch multiple setState() calls into a single update for performance.
Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
To know the updated state value, please use useEffect
hook.
You can print the updated state value like the following:
useEffect(() => { console.log(cart); }, [cart]);