反应和数据绑定

时间:2015-07-28 20:47:58

标签: reactjs

我有一个父和子组件对,让我坚持使用数据绑定。

顶级组件将呈现新的Question组件:

<Question updateScore={this.updateScore} />

updateScore方法只会使用数值更新哈希值。那不是太重要。问题组件非常简单:

var Question = React.createClass({
  getInitialState: function () {
    return { options: blahBlahBlah };
  },

  updateScore: function(optionLabel) {
    this.props.updateScore(optionLabel);
  },

  render: function() {
    var optionList = this.state.options.map(function(option) {
      return (
        <QuestionItem optionLabel={option.optionLabel} description={option.description}
                      updateScore={this.updateScore} key={option.key} />
      );
    }.bind(this));

    return (
      <ul>
        {optionList}
      </ul>
    );
  }
});

问题项目组件甚至更简单:

var QuestionItem = React.createClass({
  render: function() {
    return (
      <li onClick={this.props.updateScore.bind(this, this.props.optionLabel)}>
        {this.props.description}
      </li>
    );
  }
});

问题在于当前的实现,控制台吐出了这个错误:

"Warning: bind(): React component methods may only be bound to the component instance. See Question"

此外,如果我注销正在更新的分数的值,那么我看到它不会更新任何键但是插入一个未定义的:

{ labelOne: 0, labelTwo: 0, undefined: NaN }

我该如何约束这个?

3 个答案:

答案 0 :(得分:19)

实际反应auto-binds methods to the current component

scope.props.updateScore.bind(null, this.props.optionLabel)

通过提供null代替this,您将允许React做自己的事情。

答案 1 :(得分:3)

编辑:此问题在编辑问题之前发布。我保留它是因为它可以在将来帮助其他人

当您在函数后执行this.props.updateScore时,您将函数的结果传递给Question组件。这样,当您致电this.props.updateScope时,您只会获得该功能的结果,而不是执行该功能。

您需要将其引用传递下来,以便Question组件可以执行或绑定到它。这样,当您调用this.props.updateScope()时,您将获得一个函数并可以使用this.props.updateScope.bind(this)执行它,或者绑定到它()

删除这里的<Question updateScore={this.updateScore} />

set
{
    if (this.operationLog != value)
    {
        this.operationLog = value;
        System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            System.Action a  = () => handler(this, new PropertyChangedEventArgs("OperationLog"));
            System.Windows.Forms.Form.ActiveForm.Invoke(a);
        }
    }
}

你应该好好去

答案 2 :(得分:0)

This warning is legitimate since your code is binding QuestionItem instead of Question to updateScore(). I'd suggest one of two options:

1) Since you have the optionLabel property in Question, bind the function there so it can used the correct this.

var optionList = this.state.options.map(function(option) {
  return (
    <QuestionItem optionLabel={option.optionLabel} description={option.description}
                  updateScore={this.updateScore.bind(this, option.optionLabel)} key={option.key} />
  );
}.bind(this));

2) If you want to keep the binding within QuestionItem, use a wrapper function like so

var wrapperFunc = function(optionLabel) {
      this.props.updateScore(optionLabel);
}.bind(this, this.props.optionLabel);

return (
  <li onClick={wrapperFunc}>
    {this.props.description}
  </li>
);