I'm using this function to remove an item from my state array in React
removeProduct(index) {
this.setState(prevState => ({
selectedProducts: update(prevState.selectedProducts, {$splice: [[index, 1]]}),
}))
}
it is being passed through like this:
<Basket items={this.state.selectedProducts} removeItem={this.removeProduct.bind(this)}/>
<BasketItem product={product} key={index} remove={this.props.removeItem}/>
and then called like this:
<button onClick={props.remove.bind(this)}>x</button>
but its not removing that specific item. Its only removing the first item in the array.
Can anyone help?
From your BasketItem (or wherever the button is) you need to lift a unique identifier up to the removeProduct
function. I'm assuming the removeProduct
is somewhere in a parent of BasketItem.
When the button is clicked, BasketItem's onRemoveProduct is called. That in turn calls it's prop with the id of the the item. The parent (Basket) onRemoveProduct then knows what product to remove the basket.
See code below.
Note: Do not use the index from .map as the key. You need to use some identifying item on the product.
Example: * you have 3 items with index and key = (0,1,2).
React renders the 3 items
You remove the 2nd item (key = 1) and then the array.map happens again.
It returns 2 items with keys = (0,1).
React sees that the items have changed and that the item with key = 2 (the last item) is missing.
Item 2 (the last item, is removed, leaving the first two in place.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [
{
id: 0,
name: "Product 1"
},
{
id: 1,
name: "Product 2"
},
{
id: 2,
name: "Product 3"
}
]
};
this.handleRemoveProduct = this.handleRemoveProduct.bind(this);
}
handleRemoveProduct(e) {
const products = this.state.products.filter(prod => prod.id !== e)
this.setState({products})
}
render() {
return (
<div>
<ul>
{this.state.products.map((product, index) => {
return (
<BasketItem
key={product.id}
product={product}
onRemoveProduct={this.handleRemoveProduct}
/>
);
})}
</ul>
</div>
);
}
}
class BasketItem extends React.Component {
constructor(props) {
super(props);
this.onRemoveProduct = this.onRemoveProduct.bind(this);
}
onRemoveProduct(e) {
e.preventDefault();
this.props.onRemoveProduct(this.props.product.id)
}
render() {
return (
<li>
{this.props.product.name}
<button onClick={this.onRemoveProduct}>X</button>
</li>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>