How to map an array with unknown nesting levels?

Viewed 624

I have an array of comments which can have answers, so every element (comment) of the array can have nested elements (comments) and the nesting level is unknown, but I need to render this array in ReactJs to display these comments with the given nesting level.

comment 1
-- comment 2
-- comment 3
---- comment 4
-- comment 5
comment 6
-- comment 7

Something like this. But I have no idea how to do this.

I would like to see an example how to render it with ReactJs, but an example how to map such arrays in JavaScript would be helpful as well.

My array is more complex then an array of strings, but let's imagine that this is like

[
  {
    "value": "awesome",
    "comments": [
      {
        "value": "thanks"
        "comments": null
      },
      {
        "value": "really awesome",
        "comments": [
          "value": "thanks again",
          "comments": null
        ]
      }
    ]
  }
]

I hope this example will help.

2 Answers

You would use a recursive function. Recursive means that the function calls itself, or in the case of React, a component that returns itself as a child.

Here is an example which renders the value as a paragraph element, and then renders the child comments.

function Comment(props) {
    return (<>
        <p>{props.value}</p>
        {props.comments ? 
            props.comments.map(comment => {
                return <Comment comments={comment.comments} />
            })
        : null}
    </>)
}

You can render its recursively

const data = [
  {
    "value": "awesome",
    "comments": [
      {
        "value": "thanks"
        "comments": null
      },
      {
        "value": "really awesome",
        "comments": [
          "value": "thanks again",
          "comments": null
        ]
      }
    ]
  }
]

const CommentItem = (props) => {
  return (
    <div>{props.item.value}</div>
    {
      Array.isArrray(props.item.comments) && 
      props.item.comments.length >= 1 &&
      props.comments.map(comment => (
        <CommentItem item={comment.comments}/>
      )
    }
  )
}

return data.map(comment => <CommentItem item={comment}/>)
Related