[TIL] 2022-03-26
오늘의 TIL
Self Study
- 게시판에 댓글 기능 추가하기
: 댓글 생성, 조회, 수정, 삭제 (+별점⭐️)
오늘은 하루종일 댓글 CRUD를 구현했다.
일단 댓글은 게시판에 속해있기 때문에 하나하나 조회하는 게 아니고 리스트 형태로 게시판의 아이디를 활용한다는 것이 게시판과 달랐다.
그리고 게시판은 List에서는 목록조회, Detail에서는 상세 조회, Write에서는 생성/수정으로 한 화면 당 기능이 한두개였던 것에 비하여, 댓글은 CRUD가 BOARD_DETAIL 화면 안에서 전부 이루어지기 때문에, 컴포넌트를 어디에서 진입하게 해야 하는지 고민이 필요했다.
export default function BoardsDetailPage() {
const router = useRouter();
const boardId = String(router.query.boardId);
return (
<>
<BoardDetail />
<CommentWrite />
<Comments />
</>
);
}
우선 각 기능 별로 컴포넌트를 생성하고, BoardDetail의 return문에 댓글의 컴포넌트들을 전부 입력했더니 화면이 이어져서 나왔다. 짱 좋고 신기햇,,
화면을 연결하고 나서는 기존의 게시판과 비슷하게 작업을 했다.
그런데 별점이 생각보다 어려웠다!!!
일단 댓글을 생성할 때 별점을 누르면 누른 별점의 id를 setRating하고, emotion에도 눌렸는지 상태값 여부를 통해 눌린 별점의 색을 다르게 표현할 수 있어서 간단했는데,
/*CommentWrite*/
//Presenter
const onClickStar = (e: MouseEvent<HTMLButtonElement>) => {
if (e.target instanceof Element) {
setRating(Number(e.target.id));
}
};
//Presenter
<S.CStar id="1" isStar={props.rating >= 1} onClick={props.onClickStar}>/S.CStar>
...
<S.CStar id="5" isStar={props.rating >= 5} onClick={props.onClickStar}>/S.CStar>
//Emotion
export const CStar = styled.button`
background-image: ${(props: any) =>
props.isStar
? "url('/boards/detail/comment/CYellowStar.png')"
: "url('/boards/detail/comment/CGrayStar.png')"};
`;
조회할 때는 어떻게 표현을 해줘야 하나.... 참 고민이 되었다.
처음에는 삼항 연산자를 썼다가,, 조건이 너무 많아져서 if문을 쓰다가,, switch문도 써보고,,, 별점 보여주는 거 하나에 코드가 40~50줄을 넘어가고,,,, for문이나 map 안에서 setState를 쓰면 리렌더를 너무 많이 했다면서 에러가 발생했다,,ㅎㅎ 미안해 맥북아 고생햇서ㅜ
그렇게 이것저것 고치다보니까 결국 presenter에서 rating 값으로 조건문을 주는 방법을 떠올릴 수 있었고, 어마무시한 더러운 코드를 전부 지울 수 있었다. 혼자 거의 4시간? 더 넘게? 고민한 것 같은데 이런 저런 방법이 자꾸만 떠올라서 너무 재밌었다 ㅋㅋㅋㅋㅋ
👇🏻 처음에 시도한 노가다의 흔적..ㅎㅎㅎㅎㅎ
별점을 성공하고 자신감이 붙어서 수정도 해봤는데, 수정을 하려니까 애초에 댓글을 보여줄 때(fetchComments) 수정인지 상세보기인지 구분할 필요가 있었고, 그래서 comment List 안에 listItem을 또 빼서 List는 목록을 뿌리는 map만 넣어놓고 개별 하나하나의 댓글은 ListItem에서 수정인지 조회인지 구분해서 뿌려주도록 구현했다.
export default function CommentsUI(props: ICommentsUIProps) {
return (
<>
<S.CListWrapper>
{props.data?.fetchBoardComments.map((el: any) => (
<CommentsItemUI
key={el._id}
el={el}
data={props.data}
onClickDelete={props.onClickDelete}
/>
))}
</S.CListWrapper>
</>
);
}
이제 수정을 눌렀을 때 기존의 입력값을 보여주는 것과 수정하고 나서 수정 화면을 다시 상세 화면으로 돌리는 것만 추가하면 완ㅋ벽ㅋ한 댓글이 완성된다! 신난다! 굿~~!
Author And Source
이 문제에 관하여([TIL] 2022-03-26), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@e_juhee/TIL-2022-03-26저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)