根据官方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')
);