Skip to content
Advertisement

On clicking a button to add elements to an array in javascript, each time console.logging the array is returned with one less element

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]);
Advertisement