当按相反顺序插入元素时,ReactJS会重新初始化iframe



根据官方React教程,我使用React来填充注释的反向呈现。这是我的代码的JSBin。

你会注意到我已经嵌入了一个Youtube视频作为一个现有的评论。按播放键播放视频。现在,输入一条注释。您会注意到注释被插入到视频上方,并且视频被重新初始化。

如果我更改代码以按时间顺序加载帖子,则在添加新评论时视频将继续播放。

为什么在按时间倒序添加评论时视频会重新初始化?据我所知,React应该在内容发生变化时智能地删除和插入新节点。

每个React组件实例都有一个"key"属性,这是用来识别组件的唯一标识符。这就是React如何执行DOM区别(即:"自从上次渲染以来,这个特别的评论有改变吗?")。

由于您提供的代码没有在实例上定义键,因此React根据注释的索引为每个注释分配一个键。当评论按倒叙时间顺序插入时,视频评论的索引(以及键)从0变为1,DOM发生了变化,从而重新初始化iframe。

我已经添加了一个变量num_comments到你的代码,它通过分配一个新的comment_id每次添加新的评论修复了关键问题。

JSBin: http://jsbin.com/wofuteyive/1/edit?js输出

完整的代码如下:

var num_comments = 0;
var Comment = React.createClass({
  render: function() {
    var rawMarkup = this.props.children.toString();
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
      </div>
    );
  }
});
var CommentBox = React.createClass({
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    comments.unshift(comment);
    num_comments++;
    this.setState({comment_id: num_comments, data: comments});
  },
  getInitialState: function() {
    return {data: [{
        comment_id: 0,
        author: 'Eric',
        text: '<iframe width="560" height="315" src="https://www.youtube.com/embed/NAm1JMDZEvI" frameborder="0" allowfullscreen></iframe>'
    }]};
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});
var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment, index) {
      return (
        <Comment author={comment.author} key={comment.comment_id}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});
var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});
React.render(
  <CommentBox />,
  document.getElementById('content')
);

最新更新