admin管理员组

文章数量:1429494

I want to remove object from my list by clicking on delete icon, but with my logic either everything is deleted from list or nothing, I am not sure how to do it without provided ID to object, I don't have anything unique and I am kinda lost. Component that renders as many Food as there is in useState:

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

Logic for removing that particular item that is selected (which is not working and also bad solution since there can be case where you get same name and price twice)

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;

List of objects looks like this:

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

I want to remove object from my list by clicking on delete icon, but with my logic either everything is deleted from list or nothing, I am not sure how to do it without provided ID to object, I don't have anything unique and I am kinda lost. Component that renders as many Food as there is in useState:

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

Logic for removing that particular item that is selected (which is not working and also bad solution since there can be case where you get same name and price twice)

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;

List of objects looks like this:

[{
  foodName: "Njoki with sos"
  foodPrice: 35
  numberOfPortions: 1
}, 
{
  foodName: "Chicken Wingos"
  foodPrice: 45
  numberOfPortions: 2
}]
Share Improve this question edited Oct 7, 2020 at 8:28 Fraction 13k5 gold badges32 silver badges52 bronze badges asked Oct 6, 2020 at 14:11 MatejMatej 597 bronze badges 2
  • You think of this const [cartFood, setCartFood] = useState([]); or something else? – Matej Commented Oct 6, 2020 at 14:52
  • As long as your list items aren't overly large and your list is very long, you can also just pare the list items as string: cartFood.filter((el) => JSON.stringify(el) !== JSON.stringify(cartFood)) – Jan-Philipp Marks Commented Oct 6, 2020 at 15:00
Add a ment  | 

3 Answers 3

Reset to default 3
  • Put the index of the item in the array as the id. Pass it as your id.
 {cartFood.map((food, index) => {
              return (
                <CartFood
                  key={index}
                  id={index}
                  foodName={food.foodName}
                  foodPrice={food.foodPrice}
                  numberOfPortions={food.numberOfPortions}
                  cartFood={cartFood}
                  setCartFood={setCartFood}
                />
              );
            })}
  • Use the id to remove the food.
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>
  );
};

Something like this should work :

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

Your button (icon) should call this function with current object data (obj)

A working example : https://codesandbox.io/s/cart-isz6c?file=/index.js

From what I see in your repo:

  1. Just pass the food._id to FoodCard so you access it when you want to add or remove an item from cart:

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));
  };

Working example:

  1. You could use useReducer with useContext so you don't have to pass props down manually at every level, check this article for more info

  2. You don't need to pass the cartFood as a property just for updating the state since you can use setState callback:

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

本文标签: