39 - Comment Section with Nested Replies

Description

Develop a React component that displays a comment section accommodating nested replies, enabling users to post comments and respond to others.

  • Renders a list of comments, each with:

    • Author name

    • Comment content

    • Nested replies (if any), displayed hierarchically

    • Timestamp

    • Optional features:

      • Edit/delete functionality

      • Like/dislike buttons

  • Allows users to create new comments.

  • Facilitates posting replies to existing comments, maintaining nesting structure.

Algorithm

  1. Component Structure:

    • Define a functional component named CommentSection.

    • Accept props for:

      • comments: Array of comment objects (id, author, content, timestamp, replies, etc.).

      • onNewComment: Function to handle new comment creation.

      • onReply: Function to handle reply posting.

    • Maintain internal state for:

      • newCommentContent: Text for a new comment being composed.

      • Potentially track reply targets for nested comment submission.

  2. Comment Rendering:

    • Recursively iterate through the comments array.

    • For each comment:

      • Display author, content, timestamp, and optional features.

      • Recursively render nested replies, ensuring visual hierarchy (indentation, etc.).

  3. New Comment Creation:

    • Provide an input field for users to compose new comments.

    • Attach a submit button to trigger the onNewComment prop function with the entered text.

  4. Replying to Comments:

    • Implement a mechanism (e.g., "Reply" button) to initiate a reply to a specific comment.

    • Track the target comment for the reply.

    • Provide an input field for composing the reply.

    • Attach a submit button to trigger the onReply prop function with the reply content and target comment ID.

Code

import React, { useState } from 'react';

const Comment = ({ comment, onReply }) => {
  const [replyContent, setReplyContent] = useState('');

  const handleReplySubmit = (event) => {
    event.preventDefault();
    onReply(comment.id, replyContent);
    setReplyContent(''); // Clear reply input after submission
  };

  const renderReplies = () => {
    if (comment.replies && comment.replies.length > 0) {
      return comment.replies.map((reply) => (
        <Comment key={reply.id} comment={reply} onReply={onReply} />
      ));
    }
    return null;
  };

  return (
    <div className="comment">
      <p className="author">{comment.author}</p>
      <p className="content">{comment.content}</p>
      <p className="timestamp">{comment.timestamp}</p>
      {/* Add optional features like edit/delete buttons and like/dislike here */}
      {replyContent && (
        <form onSubmit={handleReplySubmit}>
          <input
            type="text"
            placeholder="Write your reply..."
            value={replyContent}
            onChange={(event) => setReplyContent(event.target.value)}
          />
          <button type="submit">Reply</button>
        </form>
      )}
      {renderReplies()}
      <button onClick={() => setReplyContent(!replyContent)}>
        {replyContent ? 'Cancel Reply' : 'Reply'}
      </button>
    </div>
  );
};

const CommentSection = ({ comments, onNewComment, onReply }) => {
  const [newCommentContent, setNewCommentContent] = useState('');

  const handleNewCommentSubmit = (event) => {
    event.preventDefault();
    onNewComment(newCommentContent);
    setNewCommentContent(''); // Clear new comment input after submission
  };

  return (
    <div className="comment-section">
      <h2>Comments</h2>
      <form onSubmit={handleNewCommentSubmit}>
        <input
          type="text"
          placeholder="Write your comment..."
          value={newCommentContent}
          onChange={(event) => setNewCommentContent(event.target.value)}
        />
        <button type="submit">Comment</button>
      </form>
      {comments.map((comment) => (
        <Comment key={comment.id} comment={comment} onReply={onReply} />
      ))}
    </div>
  );
};

export default CommentSection;

Explanation

  • Comment component: Displays individual comments and handles nested replies.

  • CommentSection component: Renders the main comment list and input fields for new comments.

  • State management: Both components use separate state for their respective input fields.

  • Reply system:

    • Clicking "Reply" on a comment sets the state to show the reply input field.

    • onReply prop function receives the target comment ID and the entered reply content.

  • Recursive rendering: Comment component renders itself again for each nested reply, creating a hierarchical structure.

  • Optional features: Add code for edit/delete functionalities and like/dislike buttons based on your requirements.

Additional Notes

  • This is a basic example and can be further customized with styling, animations, error handling, and various input/display enhancements.

  • Consider user experience aspects like visual cues for indicating reply nesting levels and accessibility features for keyboard navigation.

Last updated