简体   繁体   中英

Delete mapped element by click React

In my state I have an array, which I mapped in render function:

State

this.state = {
        newItem: {
            name: "",
            amount: 0
        },
        products: [
            {
                name: "Item",
                amount: 5
            },
            {
                name: "Item",
                amount: 5
            },
            {
                name: "Item",
                amount: 5
            }
        ]
    }

I want to delete element from the array products by clicking in button of that element. But what I attempted to do, everything fails. I searched a lot and find logically the most common solution but it didn't work too. Here is the delete function:

Delete function

delete(e) {
  this.setState(prevState => ({ products: prevState.products.filter((product) => {
      return product !== e.target.value
  })}))
  console.table(this.state.products)
}

Mapped JSX code

            {
                this.state.products.map((item, index) => {
                    return(
                        <div key={index}>
                            <input readOnly value={this.state.products[index].name} type="text" />
                            <button disabled>-</button>
                            <input readOnly value={this.state.products[index].amount} type="number" />
                            <button disabled>+</button>
                            <button onClick={(e) => this.delete(e)}>Delete</button>
                        </div>
                    )
                })
            }

You need to pass index of that element into delete which will be removed like below.

<button onClick={() => delete(index)}>Delete</button>

Then you can remove that element easily.

delete = index => {
  this.setState(prevState => 
    ({
        products: prevState.products.filter((product, i) => i !== index)
    })
  );
}

A simplified example of how to make item specific buttons on a mapped list:

delete = (id) => {
  this.setState(products: this.state.products.filter((item, index) => index !== idx));
}

here is the solution and working example here https://codesandbox.io/s/dawn-tdd-js8yz

 state = { newItem: { name: "", amount: 0 }, products: [ { name: "Item1", amount: 5 }, { name: "Item2", amount: 5 }, { name: "Item3", amount: 5 } ] } delete(e: any) { var products = this.state.products.filter((product) => { return product.name.== e;name }). console.log(products) this:setState({products. products}) console.table(this.state.products) } render() { const { products } = this;state. return ( <> {products,map((x. index) => { return <div key={index}> <input readOnly value={this.state.products[index].name} type="text" /> <button disabled>-</button> <input readOnly value={this.state.products[index].amount} type="number" /> <button disabled>+</button> <button onClick={this.delete,bind(this, x)}>Delete</button> </div> })} </> ) }

Note that setState is asynchronous , so using console.log(this.state.products) immediately after calling setState will not print the updated products. You can pass a callback in the second parameter of setState , it will be executed once setState is completed.

The other problem comes from the delete function. You are using e.target.value which is an empty string because the button has no value.

You can fix this with the following code:

delete(product) {
  this.setState(prevState => ({
    products: prevState.products.filter(p => p !== product)
  }), 
  () => console.log(this.state.products));
}

In the JSX code, I pass the product in the first argument of the delete function:

{
  this.state.products.map((product, index) => (
    <div key={index}>
      <input readOnly value={product.name} type="text"/>
      <button disabled>-</button>
      <input readOnly value={product.amount} type="number"/>
      <button disabled>+</button>
      <button onClick={() => this.delete(product)}>Delete</button>
    </div>
  ))
}

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