Pollux 01
Pollux 01

Reputation: 121

Value not getting passed from child to parent component in React

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

Answers (2)

Shubham Khatri
Shubham Khatri

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

Sujit.Warrier
Sujit.Warrier

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

Related Questions