yerassyl
yerassyl

Reputation: 3048

props as callback to parent of parent in react.js

I know how to set callback using props to parent component. I do that as in official react tutorial. But suppose I want to pass props to parent of parent. Suppose I have components as follows:

AllergyBox
  AllergiesList
    Allergy
  

I want to implement allergy delete function. AllergyBox owns the state of list of allergies and passes it down as prop. Whenever Allergy delete button is clicked i want to delete that Allergy and refresh UI. So what i try:

var Allergy = React.createClass({
    deleteAllergy: function(e){
        e.preventDefault();
        var allergy_id = this.props.id;
        this.props.onAllergyDelete({
           id: allergy_id
        });
    },
    render: function(){
        return(
            <li>{this.props.name} <a href="#" onClick={this.deleteAllergy}> </a></li>
        )
    }
});

And Allergy List looks like that:

var AllergiesList = React.createClass({
    getDefaultProps: function(){
      return {allergies: []}
    },
    sendAllergyDelete: function(id){
      this.props.onSendAllergyDelete({
          id: id
      })
    },
    render:function(){
        var allergies = this.props.allergies.map(function(allergy){
            return(
                <Allergy name={allergy.name} key={allergy.id} id={allergy.id} onAllergyDelete={this.sendAllergyDelete} />
            )
        });
        return(
            <ul>
                {allergies}
            </ul>
        )
    }
});

And I have AllergyBox component that should handle my delete:

var AllergyBox = React.createClass({

    getInitialState: function(){
      return {
          allergiesList: [],
          form: []
      }
    },
    
    handleAllergyDelete: function(id){
      alert(id);
    },
    render: function(){
        return(
            <div className="allergies">
                <AllergiesList allergies={this.state.allergiesList} onSendAllergyDelete={this.handleAllergyDelete} />
            </div>
        )
    }
});

But I have error in Allergy component:

this.props.onAllergyDelete is not a function

I am new to React, so I don't know what is the best solution to pass something up through the components hierarchy.

Upvotes: 1

Views: 204

Answers (2)

yerassyl
yerassyl

Reputation: 3048

Ok, I found the solution.

var that = this;
var allergies = this.props.allergies.map(function(allergy){
    return(
         <Allergy onAllergyDelete={that.handleAllergyDelete} name={allergy.name} key={allergy.id} id={allergy.id} />
         )
});
I declared variable that to be equal to this (component). So, inside .map I could use that.handleAllergyDelete.

Upvotes: 0

Oleksandr T.
Oleksandr T.

Reputation: 77482

You need set this for .map in AllergiesList, because by default this in .map callback refers to global scope(in browser it is window) or if you use strict mode this will be undefined. When you pass this.sendAllergyDelete as a argument, you don't pass reference to function - you pass window.sendAllergyDelete that equal undefined, because in window there is no sendAllergyDelete function

var allergies = this.props.allergies.map(function(allergy) {
  return (
    <Allergy 
      name={allergy.name} 
      key={allergy.id} 
      id={allergy.id} 
      onAllergyDelete={this.sendAllergyDelete} />
  )
}, this);
   ^^^^

Upvotes: 1

Related Questions