无法将数据发送到 useState 数组并在 React 中映射数组

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

我在 React 中使用 API 来获取少量对象,并将数据保存到名为 'products' 的 useState 数组中。 产品列表中的每个产品都有一个名为 'Add to cart' 的按钮。 触发此按钮时,产品从列表中消失并添加到购物车(添加到名为 'addedProducts' 的第二个 useState 数组)

我这里有两个问题:

  1. 当我点击“添加到购物车”时,产品列表中的第一个元素没有添加到次要列表中。
  2. 用于显示已添加产品的第二个地图功能未被触发,并且不显示二级列表“addedProducts”中的对象。

代码:

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;

谁能告诉我哪里出了问题?

这是我的页面的样子

编辑:我无法映射,因为在映射函数中我使用 {} 而不是 () 来创建 div 元素。

替换为:

setAddedProducts(products[id]);

有了这个:

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

您正在用对象覆盖初始数组。

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

只是对之前给出的答案的一个小更新。将控制台日志放在 addProduct 函数之外。在 App 函数体内。否则您将看不到更新后的 addedProducts.

function App() {

   ...

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

  console.log(addedProducts)

  return (
   ...
  );
}

export default App;

按如下方式更新您的第二个数组。如果 addedProducts 状态确实包含元素。那么它不应该显示 ''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>

您的 addProduct() 函数应更改为以下代码。将商品添加到购物车数组时您做错了。 其次,您可以从数组中删除项目而不是显示 none。 您不能只修改原始数组,所以我们必须借助临时变量。

另外 console.log() 会 return 你是旧数组,因为 useState 是异步的 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);
}