【问题标题】:React remove object from list of objects without unique value, using hooks使用钩子从没有唯一值的对象列表中反应删除对象
【发布时间】:2021-01-21 10:31:21
【问题描述】:

我想通过单击删除图标从列表中删除对象,但是根据我的逻辑,要么从列表中删除所有内容,要么什么都没有,如果没有提供对象 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
}]

【问题讨论】:

  • 你想到这个const [cartFood, setCartFood] = useState([]);还是别的什么?
  • 只要您的列表项不是太大并且您的列表很长,您也可以将列表项作为字符串进行比较:cartFood.filter((el) => JSON.stringify( el) !== JSON.stringify(cartFood))

标签: javascript reactjs react-hooks


【解决方案1】:
  • 将数组中项目的索引作为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>
  );
};

【讨论】:

  • 嗯......我想我搞砸了,因为你的灵魂应该可以工作,但购物车中的所有东西都被删除了,不仅仅是那个特定的项目......
  • 是的,我试图建议编辑,但我不能,因为它只有一个字符,问题仍然存在,所有东西都从购物车中删除,不仅是特定项目,是否有可能我弄乱了其他东西?也许我需要传播一些东西?
  • 再次检查,代码应该可以工作。我已经更新了。您需要检查过滤器函数中作为道具的 id。
  • @PrateekThapa 如果项目的顺序可能发生变化,不建议对键使用索引:medium.com/@robinpokorny/…
【解决方案2】:

这样的事情应该可以工作:

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

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

一个工作示例:https://codesandbox.io/s/cart-isz6c?file=/index.js

【讨论】:

  • 我用@Prateek 的解决方案更新了我的代码,我可以在你这里显示的函数上使用 id 吗?
  • 我试过了,还是一样,没有任何反应,具体商品还在购物车里,我不知道怎么了...
【解决方案3】:

从我在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));
  };

工作示例:

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

  2. 您不需要将cartFood 作为属性传递只是为了更新状态,因为您可以使用setState callback

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

【讨论】:

  • 嗯...我在代码沙箱上打开了您的示例,但是当我想从购物车中删除商品时,什么也没发生:/ p.s.感谢您的文章肯定会阅读它
猜你喜欢
  • 2021-06-06
  • 2021-09-14
  • 2016-11-14
  • 2018-07-08
  • 1970-01-01
  • 2019-12-11
  • 2021-12-08
  • 2022-09-29
  • 2019-07-02
相关资源
最近更新 更多