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.