如何使用钩子更新状态对象中的特定值?

How to update a specific value in state object using hooks?

我正在尝试更新购物篮中某件商品的数量,但很难让它正常工作?

我有一个让用户更新数量的输入字段,数量用于根据数量更新商品的总价,以及购物篮的总成本。

我已经设法在构成购物篮的对象数组中找到了正确的项目,但是我似乎无法使用状态挂钩更新数量,我该怎么做?

我的想法是在 if 语句中更新它,然后用具有更新数量的新对象替换旧对象...但是我不知道如何执行此操作...

这就是我目前所拥有的....

    const [basketData, setBasketData] = useState(null);

    useEffect(() => {
        setBasketData(basket);
    }, []);

    const quantityHandler = (e) => {
        basketData.forEach((basket) => {
            if (Object.values(basket).includes(e.target.name)) {
            }
        });
    };

这是用于篮子的数据:

export const basket = [
    {
        productID: 1,
        productName: "Mountain Dew",
        isAgeRestricted: false,
        productDescription: "Carbonated citrus flavoured soft drink",
        unitPrice: 1.8,
        quantity: 2,
    },
    {
        productID: 2,
        productName: "Desperados",
        isAgeRestricted: true,
        productDescription: "Beer with flavourings and Tequila",
        unitPrice: 2.6,
        quantity: 6,
    },
    {
        productID: 3,
        productName: "Jack Daniels",
        isAgeRestricted: true,
        productDescription:
            "A perfect mix of Jack Daniel's Old No. 7 Tennessee Whiskey & cola",
        unitPrice: 3.35,
        quantity: 4,
    },
];

您使用 quantityHandler onClick 吗?像这样:

const quantityHandler = (e) => {
  let newDataArray = basketData.map((basket) => {
      if (basket.includes(e.target.name)) {
         return {...basket, quantity: e.target.value}
      }
      return basket;
  });
  setBasketData([...newDataArray])
};

当你做更复杂的事情时,你会使用 map 而不是 forEach。 returning: {...basket, quantity: value} 将 return 数组 + 该对象的更新数量。如果它不包含正确的名称,它只是 return 项目。 然后将旧数组设置为更新后的数组。

除了 includes 你也可以做 if(basket.name === e.target.name),它看起来更准确:)

这是一个完整的解决方案(也可在 https://stackblitz.com/edit/react-basket55?file=src/App.js 获得):

import React, { useState, useEffect } from "react";
import "./style.css";

export default function App() {
  const basket = [
    {
      productID: 1,
      productName: "Dew",
      quantity: 1
    },
    {
      productID: 2,
      productName: "Bud",
      quantity: 1
    },
    {
      productID: 3,
      productName: "Jack",
      quantity: 1
    }
  ];

  const [basketData, setBasketData] = useState(basket);

  function handleInputChange(e) {
    let newDataArray = basketData.map(basketItem => {
      if (basketItem.productName == e.target.form.itemName.value) {
        let x = e.target.form.itemQuantity.value
          ? e.target.form.itemQuantity.value
          : 1;
        basketItem.quantity = x;
      }
      return basketItem;
    });
    setBasketData([...newDataArray]);
    
  }

  return (
    <div>
      <h1>Basket Example</h1>
      <form>
        <label>
          Item:
          <select name="itemName" onChange={handleInputChange}>
            {basket.map(function(data, index) {
              return (
                <option key={index} value={data.productName}>
                  {data.productName}
                </option>
              );
            })}
          </select>
        </label>
        <br />
        <label>
          Item Quantity:
          <input
            name="itemQuantity"
            type="Number"
            onChange={handleInputChange}
          />
        </label>
      </form>
      {basketData.map(i => {
        return (
          <p key={i.productName} >
            Item: {i.productName} {i.quantity}
          </p>
        );
      })}
    </div>
  );
}