子到父数据流

时间:2014-06-01 06:08:41

标签: reactjs

我是React的新手,还在学习基础知识。看一下这里的教程:

http://facebook.github.io/react/docs/tutorial.html#callbacks-as-props

它解释了如何让父母回应孩子的事件。这是相关的代码:

var CommentBox = React.createClass({
  handleCommentSubmit: function(comment) {
    // TODO: submit to the server and refresh the list
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm
          onCommentSubmit={this.handleCommentSubmit}
        />
      </div>
    );
  }
}

然后在CommentForm组件中:

var CommentForm = React.createClass({
  handleSubmit: function() {
    var author = this.refs.author.getDOMNode().value.trim();
    var text = this.refs.text.getDOMNode().value.trim();
    this.props.onCommentSubmit({author: author, text: text});
    this.refs.author.getDOMNode().value = '';
    this.refs.text.getDOMNode().value = '';
    return false;
  },
}

如果我正确理解了这一点,那么在<CommentForm/>尝试调用CommentForm.handleSubmit()时,实例化this.props.onCommentSubmit()(没有任何属性)会创建一个损坏的引用。父母必须做<CommentForm onCommentSubmit={some.function}/>。这是在React中进行子到父数据流的官方方式吗?还是有一种更松散耦合的方式?我想我希望有更类似于Backbone的trigger()on()函数,其中一个视图可以更改它侦听的事件,而不必在其他视图中创建运行时错误。

1 个答案:

答案 0 :(得分:9)

这可能是React中组件之间传递数据的最常见形式。虽然它比基于事件的解决方案更紧密耦合,但它也更明确(由于间接性更低),并且React重点关注消除以数据流问题为中心的错误(这可能是大型Backbone应用程序中的问题)。

可重用组件通常会通过其属性提供API。例如,在CommentForm中,它将调用传递给onCommentSubmit的函数。使用the propTypes hash,组件可以使此API更加明确。可以使用.isRequired声明必需的属性,而可选属性则将其关闭。应该在没有特定属性的情况下运行的组件应检查其处理程序中是否存在这些属性,例如:

var CommentForm = React.createClass({
  handleSubmit: function() {
    if (this.props.onCommentSubmit) {
      // ...
      this.props.onCommentSubmit(...);
    }
  },
}

正如传递回调是在Node.js应用程序中处理异步数据的最常见形式一样,将函数作为属性传递是React中父子组件通信的最低通用分母,并且是最好的方法确保您构建的任何组件都可以与其他人的代码一起使用。但是,正如Node具有EventEmitters,promises,fiber等等,您可以使用大量方法在React应用程序中有效地传递数据流。一种流行的体系结构是Flux,它在应用程序级别提供了更多的灵活性,同时仍保持清晰的单向数据流;另一种是使用事件总线(例如使用EventEmitter2)。但请记住,通过转向更灵活,松散耦合的架构,可以保证您放弃。