I have the following json:
{
"comments":[
{
"id":1,
"comment_text":"asdasdadasdsadsadadsa",
"author":"adsfasdasdsad",
"post_id":1,
"ancestry":null,
"archived":false,
"created_at":"2014-10-16T23:16:44.173Z",
"updated_at":"2014-10-16T23:16:44.173Z",
"is_moderated":false,
"avatar_url":null,
"slug":null,
"blog_id":2,
"children":[
]
},
{
"id":2,
"comment_text":"idlsfghlskdhvbsldfhjdslifds\nzf\ndsf\nds\nf\ns\nf\ns\nfds\nfsdjghfsdligjhsepfiguhefdliguhefldiughfeliughnfesg\nf\nsg\ns\ng\ns\ndf\nsd\nf\nsdgsofughlefidughls;uhgsuhg.vskjfhglsiuhg.sfv",
"author":"asdsdasdad",
"post_id":1,
"ancestry":null,
"archived":false,
"created_at":"2014-10-16T23:17:02.270Z",
"updated_at":"2014-10-16T23:17:02.270Z",
"is_moderated":false,
"avatar_url":null,
"slug":null,
"blog_id":2,
"children":[
{
"id":3,
"comment_text":"fdsfdsfdsfsdfsfsdf",
"author":"sdfdsfdsfdsfds",
"post_id":1,
"ancestry":"2",
"archived":false,
"created_at":"2014-11-28T17:39:47.059Z",
"updated_at":"2014-11-28T17:39:47.059Z",
"is_moderated":false,
"avatar_url":null,
"slug":null,
"blog_id":2,
"children":[
{
"id":4,
"comment_text":"fdsfdsfdsdsfdsfds",
"author":"sdfsdfdsfsdfdsfds",
"post_id":1,
"ancestry":"2/3",
"archived":false,
"created_at":"2014-11-28T17:39:53.049Z",
"updated_at":"2014-11-28T17:39:53.049Z",
"is_moderated":false,
"avatar_url":null,
"slug":null,
"blog_id":2,
"children":[
{
"id":5,
"comment_text":"sdfdsfdsfdsfdssdfsdfdsfdsfdsfds",
"author":"sdfsdfdsfdsfdsf",
"post_id":1,
"ancestry":"2/3/4",
"archived":false,
"created_at":"2014-11-28T17:40:02.032Z",
"updated_at":"2014-11-28T17:40:02.032Z",
"is_moderated":false,
"avatar_url":null,
"slug":null,
"blog_id":2,
"children":[
]
}
]
}
]
}
]
}
]
}
As you can see, some of the comments contain a children: []
of comments. I need to create nested comments in Reactjs based on this key.
I was able to do this in a very messy jquery way, but with React I want to move away from jquery and create a pure react base of nested comments.
Any one know of any examples, ideas or way of doing this? What I have so far is:
var Comments = React.createClass({
render: function() {
<div>
<ul>
<li>sample</li>
</ul>
{this.props.children}
</div>
}
});
My idea was to loop over the comments and say if they had children just create another comment something like
for (var i = 0; i < comments.length; i++) {
<Comments>
if (children) {
<Comments></Comments>
}
</Comments>
}
But this wont really work, I could encapsulate this in a function and say:
comments: function(comments){
for (var i = 0; i < comments.length; i++) {
<Comments>
if (children) {
this.comments(comments);
}
</Comments>
}
}
Am I any where near on the right track?
You need two components: Comments and Comment.
Comment = React.createClass({
render: function(){
var comment = this.props.comment;
return <div>
<p>{comment.author} says {comment.comment_text}</p>
<Comments comments={comment.children} />
</div>
}
});
Comments = React.createClass({
render: function(){
return <div>
{this.props.comments.map(function(comment){
return <Comment key={comment.id} comment={comment} />
})
</div>
}
});
The Comment renders Comments, which in turn can render Comment nodes, etc. This recursively builds the comment structure.
This is easier to do with just the one component if you make it responsible for rendering its own children recursively:
var Comment = React.createClass({
render() {
var comment = this.props.comment
return <div>
<div dangerouslySetInnerHTML={{__html: comment.comment_text}}/>
{comment.children.length > 0 && comment.children.map((child) => {
return <Comment key={child.id} comment={child}/>
})}
</div>
}
})
If you want to do this without nesting the components so you're just rendering a flat list of <Comment>
s, you can linearise the tree of comments into a list first, e.g.
function flattenComments(comments, flatComments, level) {
for (var i = 0, l = comments.length; i < l; i++) {
var comment = comments[i]
flatComments.push({comment: comment, level: level})
if (comment.children.length > 0) {
flattenComments(comment.children, flatComments, level + 1)
}
}
}
var flatComments = []
flattenComments(comments, flatComments, 0)
var renderedComments = flatComments.map((props) => {
return <Comment {...props}/>
})
来源:https://stackoverflow.com/questions/27193722/nested-comments-in-reactjs