DEV Community

Cover image for ๐Ÿš€ New React Challenge: Nested Comments
ReactChallenges
ReactChallenges

Posted on Originally published at reactchallenges.com

๐Ÿš€ New React Challenge: Nested Comments

Flattening a comment thread into a single array works until you need to reply to a reply. Then you're faking depth with parent ids, and every edit or delete means rebuilding the whole list. A recursive tree keeps the shape of the conversation and lets you update just the branch that changed.


๐Ÿงฉ Overview

Build a threaded comments UI: render a recursive thread, then reply, edit, collapse, and delete nodes while every update returns a new tree instead of mutating the seed.

๐Ÿ‘‰ https://www.reactchallenges.com/challenges/nested-comments


โœ… Requirements

  • Render the full thread from initialComments, with replies nested inside their parent.
  • Each comment shows its author and text, and exposes reply, edit, and delete controls.
  • Comments with replies get a collapse control with aria-expanded that hides or shows only their replies.
  • Replying opens a form, appends a trimmed reply authored by "You", and closes it. Empty or whitespace-only text is rejected and the form stays open.
  • Editing opens a prefilled editor, saves a trimmed update to that comment only, or cancels to restore the original text.
  • Deleting removes the comment and its entire subtree, leaving siblings intact.
  • Deleting every comment renders an empty state.
  • All updates are immutable: neither the seed tree nor any replies array is mutated.

๐Ÿ’ก Notes

The core idea is a recursive tree update. Map the current level, recurse into replies when the target isn't the current node, and rebuild only the nodes on that path:

function updateComment(
  comments: Comment[],
  id: string,
  update: (comment: Comment) => Comment,
): Comment[] {
  return comments.map((comment) =>
    comment.id === id
      ? update(comment)
      : { ...comment, replies: updateComment(comment.replies, id, update) },
  );
}
Enter fullscreen mode Exit fullscreen mode

Reply and edit both reuse it: one callback appends a reply, the other returns { ...comment, text }.

Collapse is UI state, not tree data. Keep the collapsed ids in a Set and let rendering hide the replies, so the branch still exists in the tree.

Delete is the same walk with filter instead of map, which removes the whole subtree in one pass.


๐Ÿงช Tests

  1. renders all seed comments with replies nested under their parent
  2. shows the author and text of every comment
  3. collapses a comment's replies and keeps the comment visible
  4. expands a collapsed comment again
  5. opens the reply form under the correct comment
  6. adds a reply with the author You and closes the form
  7. rejects an empty or whitespace-only reply and keeps the form open
  8. prefills the editor with the current comment text
  9. saves an edited comment and closes the editor
  10. cancels an edit and restores the original text
  11. deletes a comment and its replies, keeping siblings intact
  12. shows the empty state when every comment is deleted
  13. never mutates the imported seed tree

Once you can update a nested comment thread immutably, you can apply the same helper to file explorers, menus, org charts, and nested settings. That's the skill this challenge gives you: thinking in trees instead of flat lists.

๐Ÿ”ฅ Start the Challenge Now

Top comments (0)