user788448
user788448

Reputation: 797

How to pass child index to parent

I need to remove one row data from array. I don't know how to pass the index of this row from child to parent. Below is my code: App.js

 state = {
      courses: [{course:'' }] 
  }
  onDelete(index){
    this.setState((prevState) => ({
      courses: prevState.courses.filter((_, i) => i !== index)
    }));  
  }
  render() {
     const courses = this.state.courses.map((course, i) => {
      return (
        <ClassItem index={i}  onDelete={this.onDelete(i)} />
      );
    });
    return (
      <div>
         {courses}
      </div>
    );
  }

Child component:

 class ClassItem extends Component {
 onDelet(index){
   this.props.onDelete(index);
 }
  render() {
    return (
      <tr>
        <td><input type="text"  placeholder="Course Name" ></input></td> 

         <td>
         <button  onClick={this.onDelete} /></td>
      </tr>
    );
  }
}

export default ClassItem;

Upvotes: 1

Views: 92

Answers (1)

Will Jenkins
Will Jenkins

Reputation: 9887

You're nearly there. In your parent you need to capture the value of your index by closing over it by declaring a function and passing it to onDelete.

render() {
   const courses = this.state.courses.map((course, i) => {
     return (
      <ClassItem index={i} onDelete={() => this.onDelete(i)} />
  )}
)}

Then in your Child, you just call the onDelete prop:

class ClassItem extends Component {

  render() {
    return (
      <tr>
        <td><input type="text"  placeholder="Course Name"></input</td> 
        <td><button onClick={this.props.onDelete}/></td>
      </tr>
    );
  }
}

export default ClassItem;

An alternative to capturing your index in the parent is to use the index that you're passing in as a prop in your child:

class ClassItem extends Component {

 render() {
    return (
      <tr>
        <td><input type="text"  placeholder="Course Name"></input</td> 
        <td><button onClick={()=>this.props.onDelete(this.props.index)}/></td>
      </tr>
    );
  }
}

Which means you only have to pass in a reference to this.onDelete, instead of wrapping it in another function:

render() {
   const courses = this.state.courses.map((course, i) => {
     return (
      <ClassItem index={i} onDelete={this.onDelete} />
  )}
)}

Edited to add:

Doh, forgot that there's another problem with using a map index like this - as you're deleting items you'll need to use a unique and unchanging key for each item so the diffing engine knows which items to keep track of. So don't use the i index when you map over your courses, use a unique key instead and use that to filter your items in this.onDelete.

Upvotes: 3

Related Questions