在React中渲染嵌套/线程注释

时间:2016-04-24 22:48:20

标签: javascript recursion reactjs

鉴于以下数组,我希望通过使用comments以线程方式呈现parentId

comments: [
    {
      id: 1,
      parentId: null
    },
    {
      id: 2,
      parentId: 1
    },
    {
      id: 3,
      parentId: 1
    },
    {
      id: 4,
      parentId: 3
    },
    {
      id: 5,
      parentId: 4
    }
  ]

我认为使用以下组件我可以通过评论进行递归,但输出并不是我所期望的(它似乎为每个人提供了一个新的<ul>元素评论。)我有新的反应和javascript,所以也许我没有正确实现递归,或者comments应该以不同的方式构建?

const Comment = (props) => (
  <li>
    {props.comment.id}
    {props.comment.children.length > 0 ?
      <Comments comments={props.comment.children}/>
      : null }
  </li>
);

const Comments = (props) => (
  <ul>
    {props.comments.map((comment) => {
      comment.children = _.filter(props.comments, {'parentId': comment.id});
      return <Comment key={comment.id} comment={comment}/>
    })}
  </ul>
);

2 个答案:

答案 0 :(得分:10)

如果将该列表转换为实际反映注释的嵌套层次结构的结构,那么您将更容易构建用于呈现它们的组件。

[
  {
    id: 1,
    children: [
      { id: 2, children: [] },
      { id: 3, children: [ ... ] }
    ]
  }
]

您可以实现一个功能来进行转换。

function nestComments(commentList) {
  const commentMap = {};

  // move all the comments into a map of id => comment
  commentList.forEach(comment => commentMap[comment.id] = comment);

  // iterate over the comments again and correctly nest the children
  commentList.forEach(comment => {
    if(comment.parentId !== null) {
      const parent = commentMap[comment.parentId];
      parent.children = (parent.children || []).push(comment);
    }
  });

  // filter the list to return a list of correctly nested comments
  return commentList.filter(comment => {
    return comment.parentId === null;
  });
}

这是一个关于如何从平面结构转到嵌套注释列表的想法。一旦完成该实现,您所需要的只是一个递归的React组件。

function Comment({ comment }) {
  const nestedComments = (comment.children || []).map(comment => {
    return <Comment comment={comment} />;
  });

  return (
    <div key={comment.id}>
      <span>{comment.text}</span>
      <a href={comment.author.url}>{comment.author.name}</a>
      {nestedComments}
    </div>
  );
}

答案 1 :(得分:0)

如果您需要一个示例,该示例需要深入了解,我为此解决了

createCommentList(comments) {


let items = comments.map((comment) => {
  return (
    <div className="border-l pl-6">
      <Comment
        key={comment.id}
        text={comment.text}
        author={comment.author}
      />
      {comment.children && this.createCommentList(comment.children)}
    </div>
  )
})

 return items
}