Reputation: 121
As you can see in the two components below, i want to delete the recipes(in app component) from a button click in the panelcomponent, i have a method in app to delete the recipe, and a prop(onclick) send to child panelcomponent. Panel then gets the index from the map of recipes, and after the button click it executes the handleDelet method to send the index back to parent. but No this is not working !
class App extends React.Component {
state={
addRecipe:{recipeName:"",ingredients:[]},
recipes:[{recipeName:"Apple",ingredients:["apple","onion","spice"]},
{recipeName:"Apple",ingredients:["apple","onion","spice"]},
{recipeName:"Apple",ingredients:["apple","onion","spice"]}]
}
handleDelete = (index) => {
let recipes = this.state.recipes.slice();
recipes.splice(index,1); //deleting the index value from recipe
this.setState({recipes}) //setting the state to new value
console.log(index,recipes)
}
render() {
return (
<div className="container">
<PanelComponent recipes={this.state.recipes} onClick={()=>this.handleDelete(index)}/>
<ModalComponent />
</div>
);
}
}
class PanelComponent extends React.Component {
handleDelete = (index) => {
this.props.onClick(index); //sending index to parent after click
console.log(index)
}
render() {
return (
<PanelGroup accordion>
{this.props.recipes.map( (recipe,index) => {
return(
<Panel eventKey={index} key={index}>
<Panel.Heading>
<Panel.Title toggle>{recipe.recipeName}</Panel.Title>
</Panel.Heading>
<Panel.Body collapsible>
<ListGroup>
{recipe.ingredients.map((ingredient)=>{
return(<ListGroupItem>{ingredient}</ListGroupItem>);
})}
</ListGroup>
<Button bsStyle="danger" onClick={()=>this.handleDelete(index)}>Delete</Button>
<EditModalComponent />
</Panel.Body>
</Panel>
);
})}
</PanelGroup>
);
}
}
Upvotes: 1
Views: 91
Reputation: 281646
Thea actual error in your code is that while using arrow function in the onClick in parent, you are passing the wrong parameter, instead of {()=>this.handleDelete(index)}
what you should write is
{(value)=>this.handleDelete(value)}
, However, that also not necessary and you could simple write {this.handleDelete}
in App since your handleDelete function is already binded and it received the values from the Child component.
render() {
return (
<div className="container">
<PanelComponent recipes={this.state.recipes} onClick={(value)=>this.handleDelete(value)}/>
<ModalComponent />
</div>
);
}
The difference in writing {()=>this.handleDelete(index)}
vs {(value)=>this.handleDelete(value)}
is that in the first case, you are explicitly passing the index that you get from the map function in your App component while in the second case, the value passed from the child component when you execute this.props.onClick(value)
is being provided to the handleDelete
function.
Upvotes: 2
Reputation: 2869
you are sending the function wrongly as props. you are sending the result of the function as props rather than the function itself
class App extends React.Component {
state={
addRecipe:{recipeName:"",ingredients:[]},
recipes:[{recipeName:"Apple",ingredients:["apple","onion","spice"]},
{recipeName:"Apple",ingredients:["apple","onion","spice"]},
{recipeName:"Apple",ingredients:["apple","onion","spice"]}]
}
handleDelete = (index) => {
let recipes = this.state.recipes.slice();
recipes.splice(index,1); //deleting the index value from recipe
this.setState({recipes}) //setting the state to new value
console.log(index,recipes)
}
render() {
return (
<div className="container">
//change here
<PanelComponent recipes={this.state.recipes} onClick={this.handleDelete}/>
<ModalComponent />
</div>
);
}
}
Upvotes: 1