Home > Enterprise >  Can't send data to a useState array and map the array in React
Can't send data to a useState array and map the array in React

Time:03-30

I use an API in React to get few objects and I save data to a useState array called 'products'. Each product from products lists has a button called 'Add to cart'. When this button is triggered, the product disapears from the list and is added to cart ( to a second useState array called 'addedProducts')

I have 2 problems here:

  1. When I click "Add to cart", the first element from products list is not added to the secondary list.
  2. Second map function for showing added products is not triggered and don't show the objects from secondary list "addedProducts".

Code:

import { useEffect, useState } from 'react';
import './App.css';

function App() {

  const [products, setProducts] = useState([]);
  const [addedProducts, setAddedProducts] = useState([]);

  useEffect(() => {
    async function getData() {
      const res = await fetch("URL");
      const data = await res.json();
      data.sort((a, b) => a.price > b.price ? 1 : -1);
      data.reverse();
      setProducts(data);
    }

    let unmounted = false;
    if (!unmounted) {
      getData();
    }

    return () => unmounted = true;
  }, []);

  function addProduct(id) {
    document.getElementById(`product_${id}`).style.display = 'none';
    setAddedProducts(products[id]);
    console.log(addedProducts)
  }

  return (
    <div className="App">
      <div className='all'>
        <div>
          <div className="box">
            <div className='checkout'>Checkout page</div>
            <hr />
            {Boolean(products.length) && products.map((product, index) => (
              <div key={index} className='display' id={"product_" index}>
                <div className='middle'>{product.name}</div>
                <div className='middle'>Price: <span className='price'>${product.price}</span></div>
                <div className='addButton' onClick={(e) => addProduct(index)}>Add to cart</div>
              </div>
            ))}
          </div>
        </div>
        <div className='box2'>
          <div className='noProducts'>No products in your shopping cart</div>
          {Boolean(addedProducts.length) && addedProducts.map((product,index) => {
            <div key={index}>
              {product.price}
            </div>
          })}
        </div>
      </div>
    </div>
  );
}

export default App;

Can anybody tell me what is wrong, please?

This is how my page looks

My page looks like that

EDIT: I couldn't map because on map function I used {} instead of () for creating a div element.

CodePudding user response:

Just a small update on previously given answers. Put the console log outside the addProduct function. Inside the App function body. Otherwise you won't see the updated addedProducts.

function App() {

   ...

  function addProduct(id) {
    document.getElementById(`product_${id}`).style.display = 'none';
    setAddedProducts([...addedProducts, products[id]]);
  }

  console.log(addedProducts)

  return (
   ...
  );
}

export default App;

Update your second array as follows. If addedProducts state does contain elements. Then it shouldn't show ''No products in your shopping cart''

        <div className="box2">
          {addedProducts.length > 0 ? (
            addedProducts.map((product, index) => {
              <div key={index}>{product.price}</div>;
            })
          ) : (
            <div className="noProducts">No products in your shopping cart</div>
          )}
        </div>

CodePudding user response:

Replace this:

setAddedProducts(products[id]);

With this:

setAddedProducts([...addedProducts, products[id]]);

CodePudding user response:

You are overriding the initial array with an object.

//Copy previous added products, and add new product at end.
   setAddedProducts([...addedProducts, products[id]]);  

CodePudding user response:

your addProduct() function should be changed as in the below code. You were doing wrong while adding items to cart array. And secondly you can remove the item from array instead of display none. You can't just modify the original array so we have to take help of temp variable.

Also console.log() would return you the older array because useState is asynchronous refer here for more

function addProduct(index) {
    // add to cart
    setAddedProducts([...addedProducts, products[index]]);

    //remove from list
    const temp = [...products].splice(index,1)
    setProducts(temp);
}
  • Related