Nested comments in Reactjs

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":"idlsfghlskdhvbsldfhjdslifdsnzfndsfndsnfnsnfnsnfdsnfsdjghfsdligjhsepfiguhefdliguhefldiughfeliughnfesgnfnsgnsngnsndfnsdnfnsdgsofughlefidughls;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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x