React使用钩子从没有唯一值的对象列表中删除对象

时间:2020-10-06 14:11:05

标签: javascript reactjs react-hooks

我想通过单击删除图标从列表中删除对象,但是根据我的逻辑,要么从列表中删除所有内容,要么什么都不删除,我不确定在没有为对象提供ID的情况下怎么做,我什么都没有独特,我有点迷茫。 呈现与useState中一样多的Food的组件:

 {cartFood.map((food) => {
    return (
      <CartFood
         key={Math.random()}
         foodName={food.foodName}
         foodPrice={food.foodPrice}
         numberOfPortions={food.numberOfPortions}
         cartFood={cartFood}
         setCartFood={setCartFood}
      />
    );
 })}

删除选择的特定商品的逻辑(这不起作用,而且解决方案不好,因为在某些情况下您可能会两次获得相同的名称和价格)

const CartFood = ({
  foodName,
  foodPrice,
  numberOfPortions,
  cartFood,
  setCartFood,
}) => {
  const handleRemoveFood = () => {
    setCartFood(
      cartFood.filter(
        (el) =>
          el.foodName &&
          el.foodPrice !== cartFood.foodName &&
          cartFood.foodPrice
      )
    );
  };

  return (
    <div className='cartFood-container'>
      <p>{foodName}</p>
      <p>x{numberOfPortions}</p>
      <p>{foodPrice}kn</p>
      <p>
        <MdDeleteForever
          className='cartFood__icon'
          onClick={handleRemoveFood}
        />
      </p>
    </div>
  );
};

export default CartFood;

对象列表如下:

[{
  foodName: "Njoki with sos"
  foodPrice: 35
  numberOfPortions: 1
}, 
{
  foodName: "Chicken Wingos"
  foodPrice: 45
  numberOfPortions: 2
}]

3 个答案:

答案 0 :(得分:2)

  • 将项目在索引中的索引作为id。将其作为您的ID。
 {cartFood.map((food, index) => {
              return (
                <CartFood
                  key={index}
                  id={index}
                  foodName={food.foodName}
                  foodPrice={food.foodPrice}
                  numberOfPortions={food.numberOfPortions}
                  cartFood={cartFood}
                  setCartFood={setCartFood}
                />
              );
            })}
  • 使用ID删除食物。
const CartFood = ({
  foodName,
  foodPrice,
  numberOfPortions,
  cartFood,
  setCartFood,
  id,
}) => {
  const handleRemoveFood = () => {
    setCartFood(cartFood.filter((el) => el.id !== id));
  };

  return (
    <div className='cartFood-container'>
      <p>{foodName}</p>
      <p>x{numberOfPortions}</p>
      <p>{foodPrice}kn</p>
      <p>
        <MdDeleteForever
          className='cartFood__icon'
          onClick={handleRemoveFood}
        />
      </p>
    </div>
  );
};

答案 1 :(得分:2)

类似的事情应该起作用:

const handleRemoveFood = (obj) => {
        setCartFood((oldList) => oldList.filter((item) => item.foodName !== obj.foodName));
    };

您的按钮(图标)应使用当前对象数据(obj)调用此函数

一个有效的示例:https://codesandbox.io/s/cart-isz6c?file=/index.js

答案 2 :(得分:1)

根据我在your repo中看到的内容:

  1. 只需将food._id传递到FoodCard,以便在要从购物车中添加或删除商品时访问它:

FoodList.js

const foodList = (typeOfList) =>
  typeOfList.map(food => {
    return (
      <FoodCard
        key={food._id}
        foodId={food._id}
        foodName={food.title}
        foodPrice={food.price}
        foodPic={food.image}
        setCartFood={setCartFood}
        cartFood={cartFood}
      />
    );
  });

FoodCard.js

const handleAddToCard = () => {
    setCartFood([
      ...cartFood,
      {
        foodId,
        foodName,
        foodPrice,
        numberOfPortions,
      },
    ]);
  };

CartFood.js

const handleRemoveFood = () => {
    setCartFood(cartFood => cartFood.filter((el) => el.foodId !== foodId));
  };

工作示例:

Edit crazy-browser-fhw9m

  1. 您可以将useReduceruseContext一起使用,这样就不必在每个级别上手动传递道具,请查看this article以获取更多信息

  2. 您不需要仅将cartFood作为更新状态的道具,因为可以使用setState callback

setCartFood(cartFood => [
      ...cartFood,
      {
        foodId,
        foodName,
        foodPrice,
        numberOfPortions,
      },
    ]);