5

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?

2 Answers 2

14

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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}/> }) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.