当前位置: 首页 > 面试题库 >

react.js从孩子那里调用父函数

漆雕修德
2023-03-14
问题内容

我知道都存在一些类似的问题,但是我很难理解今天对这个问题的正确想法并将其推断出我的处境。

我有一个简单的应用程序,ScoreBox有一个ScoreList,其中包含很多分数。我想让Score onClick调用ScoreList
handleScoreRemove。我正在显示完整的js文件,但最重要的行是第5行和第77行。

var Score = React.createClass({
  removeRecord: function(e){
      // How do I do this?
      ScoreList.handleScoreRemove(e);
  },
  render: function() {
    var team1_style = (this.props.team1_score >= this.props.team2_score) ?
        {fontWeight: 'bold'} : {};
    var team2_style = (this.props.team2_score >= this.props.team1_score) ?
            {fontWeight: 'bold'} : {};
        return (
            <tr>
              <td style={team1_style}>{this.props.team1_name}:</td><td style={team1_style}>{this.props.team1_score}</td>
              <td style={team2_style}>{this.props.team2_name}:</td><td style={team2_style}>{this.props.team2_score}</td>
              <td><a hef="#" id={this.props.id} onClick={this.removeRecord}>remove</a></td>
            </tr>
    );
  }
});

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 (
      <div className="scoreBox">
        <h1>Scores</h1>
        <ScoreList data={this.state.data} />
        <ScoreForm onScoreSubmit={this.handleScoreSubmit} />
      </div>
    );
  }
});

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 (
        <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} >
        </Score>
      );
    });
    return (
      <div className="scoreList">
        <table>
          <tbody>
            {scoreNodes}
          </tbody>
        </table>
      </div>
    );
  }
});

var ScoreForm = React.createClass({
  checkForCompleteForm: function(){
    if (this.state.team1_name.length > 0 && this.state.team2_name.length > 0 && this.state.team1_score.length > 0 && this.state.team2_score.length > 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 (
      <form className="scoreForm" onSubmit={this.handleSubmit}>
        <input
          id='team1_name'
          type="text"
          placeholder="Team1 Name"
          value={this.state.team1_name}
          onChange={this.handleChange}
        />
        <input
          id='team1_score'
          type="number"
          placeholder="Team1 Score"
          value={this.state.team1_score}
          onChange={this.handleChange}
        />
        <input
          id='team2_name'
          type="text"
          placeholder="Team2 Name"
          value={this.state.team2_name}
          onChange={this.handleChange}
        />
        <input
          id='team2_score'
          type="number"
          placeholder="Team2 Score"
          value={this.state.team2_score}
          onChange={this.handleChange}
        />
        <input type="submit" value="Post" disabled />
      </form>
    );
  }
});

ReactDOM.render(
  <ScoreBox url="/api/scores" pollInterval={2000} />,
  document.getElementById('content')
);

问题答案:

你需要handleScoreRemove通过props

var scoreNodes = this.props.data.map(function(score) {
  return <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}
    handleScoreRemove={this.handleScoreRemove.bind(this)}>
  </Score>
}, this);

并在Score组件中这样称呼它

removeRecord: function(e) {
   this.props.handleScoreRemove( /* add arguments what do you need */ );
},


 类似资料:
  • 嗨,我是一个很新的反应,有真的很难把我的头围绕着整个状态管理,通过状态和道具传递数据。我知道标准的react方式是以单向的方式向下传递数据--从父到子,我对所有其他组件都是这样做的。但是我有一个叫做Book的组件,它根据用户选择的表单“Read、wantToRead、currentlyReading和None”来改变它的“书架”状态。在我的BookList组件中,它呈现图书组件,但它需要能够读取图

  • 问题内容: 如何从父类中调用子类的函数?考虑一下: 问题答案: 那就是抽象类的目的。抽象类基本上说:从我那里继承的任何人都必须具有此功能(或这些功能)。

  • 问题内容: 假设我的父组件有两个子组件: 我从Child2获得输入,并将其传递给Parent组件(直到现在,我知道该怎么做)。但是然后我需要将该输入传递给Child1以更新其状态。 我怎样才能做到这一点? 问题答案: 希望您能得到主要想法-在Parent组件中创建一个函数,该函数将更改传递给Child1的值。ReactJS:为什么将组件的初始状态传递为prop是反模式?

  • 所以我在学习java继承,我遇到了一个我不知道如何解决的问题。 我要做的是从超类中调用一个子类构造函数。我不知道这是否有任何意义,但我会尝试用一个例子来解释我自己。 我为什么要这么做? 我希望能够主要不必处理智能手机。 我希望能够做到:

  • 问题内容: 在组件中,我需要将函数的返回值传递给属性。然后从属性需要被传递到的组件。新来的反应。不确定如何将属性从子级传递到组件。 问题答案: 您可以将函数从父级传递给子级,子级可以使用颜色调用该函数(很多操作都类似于事件处理程序)。在App中收到颜色后,使用.setState()将其分配给状态值,然后将其在render()中获取