[React + typescript] 블로그 댓글 답글 기능 만들기

LEEJAEJUN·2023년 11월 11일
0

fasttime-2024

목록 보기
4/4
post-thumbnail

✨ 과정

✅ 댓글 목록 컴포넌트 제작(수정, 삭제)
✅ 댓글 인풋 컴포넌트 제작(작성, 수정)
✅ 답글 인풋 컴포넌트 제작(위 컴포넌트 재사용)
✅ 답글 목록 컴포넌트 제작

✨ 결과물

✨ 문제점

백엔드 분들이 미리 만들어둔 DB와 API를 사용해야 하는 상황이었다. 기존에 나는 firebase만 사용해봤기 때문에 댓글 객체 안에 그 댓글의 답글 리스트까지 묶어서 보내주는 줄 알았다. 하지만...

{
    "id" : 1,
    "postId" : 1,
    "nickname" : "nickname1",
    "content" : "좋은 글 잘 보고 갑니다.",
    "anonymity" : true,
    "parentCommentId" : null,
    "createdAt" : "2023-01-01 12:30:00",
    "updatedAt" : null,
    "deletedAt" : null
  }

보다시피 parentCommentId 가 있으면 답글, 없으면 댓글인 것이어따. 이러면 댓글과 답글이 같은 레벨로 들어와서 내가 따로 댓글과 그에 맞는 답글을 묶어주는 작업이 필요했다.

어떻게 id와 parentCommentId가 일치하는 것을 하나의 댓글 묶음으로 나타낼 것인가?

물론 더 나은 방법을 찾기 위해서 멘토님들께 여쭤볼 필요가 있었다. 그 과정에서 알게된 것이 BFF(Backend for Frontend). 리팩토링할 때 사용하거나, 다음 프로젝트에서 채택할 것 같다.

import { Comment } from '@/data/comment';

interface CommentMap {
  [key: number]: Comment;
}

export const organizeComments = (comments: Comment[]) => {
  // 하나의 댓글 묶음
  const commentMap: CommentMap = {};
  // 마지막으로 출력할 정제된 전체 댓글
  const rootComments: Comment[] = [];
  // 삭제된 댓글 빼기 (delete 정보가 있으면 삭제된 댓글)
  const filteredComments = comments.filter((comment) => comment.deletedAt == null);
  // 각각의 댓글 id를 key값으로 그 댓글에 더해 children 배열을 생성
  filteredComments.forEach((comment) => {
    commentMap[comment.id] = { ...comment, children: [] };
  });
  // 부모 댓글의 children 배열에 자식 댓글을 추가하는 로직
  filteredComments.forEach((comment) => {
    // 만약 parentCommentId가 있으면(답글이면),
    if (comment.parentCommentId) {
      // 기존에 만들어둔 commentMap에서 동일한 id값에 해당하는 부모 댓글의
      // children 배열로 해당 답글을 push
      commentMap[comment.parentCommentId].children?.push(commentMap[comment.id]);
    } else {
      // parentCommentId가 없으면(부모 댓글이면), rootComment에 만들어둔 comment 객체를 push
      rootComments.push(commentMap[comment.id]);
    }
  });

  return rootComments;
};

이렇게 하면 결과적으로 하나의 부모 댓글에 여러개의 답글 배열이 담긴 댓글 묶음을 만들 수 있다.

다만 여기서 자식 댓글만 따로 하나의 컴포넌트로 만들고자 했던 내 계획에 문제가 생겼다. (이 부분은 나중에 해결한 후 다른 글로 만들 예정). 지금은 하나의 댓글 컴포넌트에서 댓글과 답글을 함께 보여주고 있다. (comment, reply)

✨ 개선 방안

인스타그램의 댓글 시스템과 비슷하게, 답글 더보기를 눌렀을 때 답글을 받아오게 만들고자 한다. 이 부분은 백엔드 팀원과 상의 후 더 나은 데이터 구조와 함께 작업할 것 같다.

profile
always be fresh

0개의 댓글