[에브리데이] 좋아요 기능 구현
[에브리데이] 프로젝트에서 구현했던 좋아요 기능을 포스팅해보려고 한다!
나는 게시글과 댓글 그리고 대댓글에 좋아요 아이콘을 생성하여 클릭 시, 좋아요를 할 수 있도록 기능을 구현하였고, 서버에게도 해당 데이터를 전달할 수 있도록 API를 연동하였다.
개발 환경
Front-End
React
Back-End
Spring Boot
구현 화면
아래의 코드는 댓글의 좋아요 기능을 구현한 것이다!
isLikeComment, likeCount의 변수는 이전에 게시글 상세 조회 api에서 서버로부터 가져온 값으로, isLikeComment는 사용자가 댓글을 좋아요했는지에 대한 상태값이며(Y 또는 N)
likeCount는 해당 댓글의 총 좋아요 개수이다.
먼저 서버로부터 받은 isLikeComment, likeCount 변수를 아래와 같이 useState로 다시 선언하고 저장하였다.
const [isLikeComment, setIsLikeComment] = useState(comment.isLikeComment); //comment.isLikeComment의 comment는 게시글 상세 조회 api에서 받은 댓글정보를 담은 배열
const [likeCount, setLikeCount] = useState(comment.likeCount);
그리고 좋아요 아이콘을 클릭 시, isLikeComment가 N이면 likeCount가 +1하도록, isLikeComment가 Y이면 likeCount가 -1하도록 분기처리를 하였고 isLikeComment의 상태값
에 따른 api 요청코드도 작성하였습니다.
따라서, isLikeComment의 값이 좋아요 아이콘을 누를때마다 Y→N→Y→N 으로 바뀌게 되어 좋아요했다가 좋아요를 취소하는 것을 반복하는 것도 가능.
Comment.js
import React, { useState } from "react";
import ReplyList from "./ReplyList";
import { Stack, Button, Divider, Box } from "@mui/material";
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import FavoriteOutlinedIcon from '@mui/icons-material/FavoriteOutlined'; //색이채워진좋아요
import FavoriteBorderOutlinedIcon from '@mui/icons-material/FavoriteBorderOutlined'; //좋아요
import "@toast-ui/editor/dist/toastui-editor.css";
import Markdown from "../../Markdown";
import * as BoardAPI from '../../../api/Board';
import { Message } from '../../Message';
import { SESSION_TOKEN_KEY } from '../../Axios/Axios';
import {
displayDateFormat,
Item,
} from "../../CommentTool";
const Comment = (props) => {
const {
comment,
postId,
handleIsInitialize,
} = props;
const index = comment.commentId;
const token = localStorage.getItem(SESSION_TOKEN_KEY);
const tokenJson = JSON.parse(atob(token.split(".")[1]));
const [isLikeComment, setIsLikeComment] = useState(comment.isLikeComment);
const [likeCount, setLikeCount] = useState(comment.likeCount);
//댓글 삭제(db)
const deleteComment = (commentId) => {
BoardAPI.deleteComment(commentId).then(response => {
Message.success(response.message);
handleIsInitialize(false);
}).catch(error => {
console.log(JSON.stringify(error));
Message.error(error.message);
})
};
//좋아요 api
const clickLike = () => {
setIsLikeComment(!isLikeComment);
const data = {
targetType: "COMMENT",
targetId: comment.commentId
};
if (!isLikeComment) {
setLikeCount(Number(likeCount) + 1);
BoardAPI.like(data).then(response => {
Message.success(response.message);
}).catch(error => {
console.log(JSON.stringify(error));
Message.error(error.message);
})
} else {
setLikeCount(Number(likeCount) - 1);
BoardAPI.likeCancel(data).then(response => {
Message.success(response.message);
}).catch(error => {
console.log(JSON.stringify(error));
Message.error(error.message);
})
}
}
return (
<>
<Box sx= key={index}>
{/* writer 정보, 작성 시간 */}
<Stack direction="row" spacing={2}>
<AccountCircleIcon sx= ></AccountCircleIcon>
<Item style=>{comment.commentWriter}</Item>
<Item sx=>{displayDateFormat(comment.commentRegistrationDate)}</Item>
{
(!isLikeComment) ?
<FavoriteBorderOutlinedIcon sx= onClick={() => clickLike()} />
:
<FavoriteOutlinedIcon sx= onClick={() => clickLike()} />
}
<span style=
onClick={() => clickLike()}>
{likeCount}
</span>
</Stack>
{/* comment 글 내용 */}
<Box
key={index}
sx=
>
<Markdown comment={comment} />
</Box>
{/* comment 삭제 */}
{tokenJson.sub === comment.writerLoginId && (
<>
<Button sx=
onClick={() => {
deleteComment(comment.commentId);
}}
>
삭제
</Button>
</>
)}
{/* 대댓글 컴포넌트 */}
<ReplyList commentId={comment.commentId} postId={postId} />
<Divider variant="middle" />
</Box>
</>
);
};
export default Comment;
마무리
좋아요 기능을 구현하는 다양한 방법이 있지만,
나는 좋아요를 클릭 시, 화면단에서 먼저 색상이 바뀌고 숫자가 바로 바뀔 수 있도록 개발하였다. 그 동시에 API요청 코드도 함께 작성하여 API 통신 후 DB에 반영된 값은 다시 렌더링
했을때 볼 수 있도록 하였다. API를 연동하여 좋아요 기능을 구현해봄으로써 state에 대한 이해를 더 높일 수 있었고 전보다 state를 사용하는 것이 더욱 수월해진 것을 느꼈다.