title: react.js call parent function from child
body: <p>I know there are a few similar questions <a href="https://stackoverflow.com/questions/24398932/reactjs-how-can-a-child-find-its-parent?rq=1">here</a> and <a href="https://stackoverflow.com/questions/31564776/react-js-onclick-function-from-child-to-parent">here</a> but I am having a tough time understanding what is the correct thinking today on this and extrapolating it to my situation.</p>
  
  <p>I have a simple app, ScoreBox has a ScoreList which has many Scores. I want to have a Score onClick call ScoreList handleScoreRemove. I am showing the full js file, but the most important lines are line 5 and line 77.</p>
  
  <pre><code>var Score = React.createClass({
    removeRecord: function(e){
        // How do I do this?
        ScoreList.handleScoreRemove(e);
    },
    render: function() {
      var team1_style = (this.props.team1_score &gt;= this.props.team2_score) ?
          {fontWeight: 'bold'} : {};
      var team2_style = (this.props.team2_score &gt;= this.props.team1_score) ?
              {fontWeight: 'bold'} : {};
          return (
              &lt;tr&gt;
                &lt;td style={team1_style}&gt;{this.props.team1_name}:&lt;/td&gt;&lt;td style={team1_style}&gt;{this.props.team1_score}&lt;/td&gt;
                &lt;td style={team2_style}&gt;{this.props.team2_name}:&lt;/td&gt;&lt;td style={team2_style}&gt;{this.props.team2_score}&lt;/td&gt;
                &lt;td&gt;&lt;a hef="#" id={this.props.id} onClick={this.removeRecord}&gt;remove&lt;/a&gt;&lt;/td&gt;
              &lt;/tr&gt;
      );
    }
  });
  
  var ScoreBox = React.createClass({
    loadScoresFromServer: function() {
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        cache: false,
        success: function(data) {
          this.setState({data: data});
        }.bind(this),
        error: function(xhr, status, err) {
          console.error(this.props.url, status, err.toString());
        }.bind(this)
      });
    },
    handleScoreSubmit: function(score) {
      var scores = this.state.data;
      // Optimistically set an id on the new score. It will be replaced by an
      // id generated by the server. In a production application you would likely
      // not use Date.now() for this and would have a more robust system in place.
      score.id = Date.now();
      var newScores = scores.concat([score]);
      this.setState({data: newScores});
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        type: 'POST',
        data: score,
        success: function(data) {
          this.setState({data: data});
        }.bind(this),
        error: function(xhr, status, err) {
          this.setState({data: scores});
          console.error(this.props.url, status, err.toString());
        }.bind(this)
      });
    },
    getInitialState: function() {
      return {data: []};
    },
    componentDidMount: function() {
      this.loadScoresFromServer();
      setInterval(this.loadScoresFromServer, this.props.pollInterval);
    },
    render: function() {
      return (
        &lt;div className="scoreBox"&gt;
          &lt;h1&gt;Scores&lt;/h1&gt;
          &lt;ScoreList data={this.state.data} /&gt;
          &lt;ScoreForm onScoreSubmit={this.handleScoreSubmit} /&gt;
        &lt;/div&gt;
      );
    }
  });
  
  var ScoreList = React.createClass({
    handleScoreRemove: function(score) {
      var scores = this.state.data;
      var index_of_score = array.indexOf(score);
      var newScores = scores.splice(index_of_score, 1);
      this.setState({data: newScores});
      $.ajax({
        url: this.props.url + "/" + score[id],
        dataType: 'json',
        type: 'DELETE',
        success: function(data) {
          this.setState({data: data});
        }.bind(this),
        error: function(xhr, status, err) {
          this.setState({data: scores});
          console.error(this.props.url, status, err.toString());
        }.bind(this)
      });
    },
    render: function() {
      var scoreNodes = this.props.data.map(function(score) {
        return (
          &lt;Score key={score.id} id={score.id} team1_name={score.team1_name} team1_score={score.team1_score} team2_name={score.team2_name} team2_score={score.team2_score} &gt;
          &lt;/Score&gt;
        );
      });
      return (
        &lt;div className="scoreList"&gt;
          &lt;table&gt;
            &lt;tbody&gt;
              {scoreNodes}
            &lt;/tbody&gt;
          &lt;/table&gt;
        &lt;/div&gt;
      );
    }
  });
  
  var ScoreForm = React.createClass({
    checkForCompleteForm: function(){
      if (this.state.team1_name.length &gt; 0 &amp;&amp; this.state.team2_name.length &gt; 0 &amp;&amp; this.state.team1_score.length &gt; 0 &amp;&amp; this.state.team2_score.length &gt; 0)
      {
        // enable the button
        $("input[type=submit]").removeAttr('disabled');
      }
  
    },
    getInitialState: function() {
      return {id: '', team1_name: '', team1_score: '', team2_name: '', team2_score: ''};
    },
   handleChange : function (e) {
      // this is a generic handle change function that uses the html id to set the state instead of
      // having a bunch of if statements
      var stateObject = function() {
        var returnObj = {};
        returnObj[this.target.id] = this.target.value;
        return returnObj;
      }.bind(e)();
      // setState is async which makes this painful
      //  JCN - why when I pass checkForCompleteForm as 2nd param it doesnt work, but instead I need this
      // function bind stuff... need to understand exactly what this is doing
      this.setState( stateObject, function(){
          this.checkForCompleteForm();
      }.bind(this));
    },
    handleSubmit: function(e) {
      e.preventDefault();
      var team1_name = this.state.team1_name.trim();
      var team1_score = this.state.team1_score.trim();
      var team2_name = this.state.team2_name.trim();
      var team2_score = this.state.team2_score.trim();
      if (!team1_name || !team1_score ) {
        return;
      }
      this.props.onScoreSubmit({team1_name: team1_name, team1_score: team1_score,team2_name: team2_name, team2_score: team2_score });
      this.setState({team1_name: '', team1_score: '', team2_name: '', team2_score: ''});
    },
    render: function() {
      return (
        &lt;form className="scoreForm" onSubmit={this.handleSubmit}&gt;
          &lt;input
            id='team1_name'
            type="text"
            placeholder="Team1 Name"
            value={this.state.team1_name}
            onChange={this.handleChange}
          /&gt;
          &lt;input
            id='team1_score'
            type="number"
            placeholder="Team1 Score"
            value={this.state.team1_score}
            onChange={this.handleChange}
          /&gt;
          &lt;input
            id='team2_name'
            type="text"
            placeholder="Team2 Name"
            value={this.state.team2_name}
            onChange={this.handleChange}
          /&gt;
          &lt;input
            id='team2_score'
            type="number"
            placeholder="Team2 Score"
            value={this.state.team2_score}
            onChange={this.handleChange}
          /&gt;
          &lt;input type="submit" value="Post" disabled /&gt;
        &lt;/form&gt;
      );
    }
  });
  
  ReactDOM.render(
    &lt;ScoreBox url="/api/scores" pollInterval={2000} /&gt;,
    document.getElementById('content')
  );
  </code></pre>