简体   繁体   中英

Delete an object from array React

I am trying to delete an object in an array in my state. I want to do this by using a onclick handler on items from a map function.

So when I click on a specific item, I have tried many things. I have tried the filter function by trying to pass down the item from the map function and then filtering out the array excluding the item provided as argument, I've tried splice but all doesn't seem to work. With splice, It always delete the last item instead of the Item I click on.

What am I not seeing? I know there are a lot of similiar questions but I've tried many of the answers over there but nothing seems to work.

Filter try

JSX

{this.state.product.ingredients.map((item) => {
  return (
     <p className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer" key={item.name} onClick={({item}) => this.deleteTag({item})}>{item.name}</p>
  );
})}

Method

deleteTag(item) {

    let product = {...this.state.product};

    product.ingredients.filter((ingredient) => {
        return ingredient !== item;
    });

    this.setState({product: product});
}

Splice

JSX

{this.state.product.ingredients.map((item) => {
  return (
     <p className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer" key={item.name} onClick={this.deleteTag}>{item.name}</p>
  );
})}

Method

deleteTag(e) {

    let product = {...this.state.product};

    var index = product.ingredients.indexOf(e.target.value)

    product.ingredients.splice(index, 1);

    this.setState({product: product});

}

Example of the array with one object (objects/items are added with another function)

ingredients: [{name: 'Salad', value: 1}],

I'm not sure that you are updating your state correctly but instead mutating it. Could you try this:

deleteTag(item) {
    this.setState(prevState => { 
      return {
        product: {
           ...prevState.product,
           ingredients: prevState.product.ingredients.filter((ingredient) => ingredient !== item)
        }
      } 
    });
}

Edit your onClick to pass the item from map :

onClick={() => this.deleteTag(item)}

filter returns a new array instead of modifying the array in place.

{...this.state.product} only creates a shallow copy, so you should not modify product.ingredients in place anyway, which is why your second attempt failed as well.

Try this:

this.setState(prevState => ({
  product: { ...prevState.product, ingredients: prevState.product.ingredients.filter(...) },
}));

You need to pass the item to your callback. You're currently using event.target.value , but your <p> element doesn't have a value . Use bind to partially apply your callback.

JSX:

{this.state.product.ingredients.map((item) => (
  <p
    className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer"
    key={item.name}
    onClick={this.deleteTag.bind(item)}>
    {item.name}
  </p>
))}

the first argument to your callback will be your item object because of the partial function application, it'll no longer be the click event. (If you still need the click event, it will be the second argument.)

Method:

deleteTag(item, /* event */) {
  let product = {...this.state.product};
  const index = product.ingredients.indexOf(item.value)

  product.ingredients.splice(index, 1);
  this.setState({product: product});
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM