Likelion-YeungNam-Univ / 12th-BeginnerFit-FE

헬스/관리/운동 등에 무지한 사람들 위해 나에게 맞는 홈트 영상 추천/운동 종목 추천 해주는 서비스
http://43.201.203.128:5173/
3 stars 2 forks source link

feat:게시물 좋아요 및 게시물 신고, 게시판 페이지네이션 구현 #43

Closed tkv00 closed 3 months ago

tkv00 commented 3 months ago

구현내용

구현코드

좋아요기능

export const useLikeApi = (post) => {
  //게시물 좋아요 개수
  const { data: likesCnt, refetch: likeCnt } = useQuery({
    queryKey: ["likesCnt", post.id],
    queryFn: async () => {
      const response = await api.get(`/posts/${post.id}`);
      //console.log("좋아요", response.data.likeCnt);
      return response.data.likeCnt;
    },
  });

  //게시글 좋아요 여부 확인
  const { data: isLiked, refetch: likeStatus } = useQuery({
    queryKey: ["likeStatus", post.id],
    queryFn: async () => {
      const response = await api.get(`/posts/${post.id}/likes/check`);
      //좋아요 되어 있으면 true
      //console.log(response);
      return response.data;
    },
    //refetchInterval: 1000, //1초마다 한 번씩 수동 통신
  });

  //Mutation
  //좋아요 토글
  const toggleLikehandler = useMutation({
    mutationFn: async () => {
      //좋아요가 되어있으면 -> 좋아요 취소
      if (isLiked) {
        await api.delete(`/posts/${post.id}/likes`);
      }
      //좋아요가 안되어있으면 -> 좋아요
      else {
        await api.post(`/posts/${post.id}/likes`);
      }
    },
    //mutation 함수 실행 전 실행.
    onMutate: async () =>
      //쿼리에서 값 불러오기
      {
        //충돌 방지
        await queryClient.cancelQueries(["likesCnt", post.id]);
        await queryClient.cancelQueries(["likeStatus", post.id]);
        //현재 좋아요 개수와 상태가져오기
        const prevLikeCnt = queryClient.getQueriesData(["likesCnt", post.id]);
        const prevLikeStatus = queryClient.getQueriesData([
          "likeStatus",
          post.id,
        ]);
        //서버 응답 기다리지 않고 업뎃
        queryClient.setQueryData(["likeStatus", post.id], !isLiked);
        queryClient.setQueryData(["likesCnt", post.id], (old) => {
          {
            return isLiked ? old - 1 : old + 1;
          }
        });
        return { prevLikeCnt, prevLikeStatus };
      },
    //에러시
    onError: (err, variables, context) => {
      queryClient.setQueryData(["likesCnt", post.id], context.prevLikeCnt);
      queryClient.setQueryData(["likeStatus", post.id], context.prevLikeStatus);
    },
    //mutation 성공시
    onSettled: () => {
      queryClient.invalidateQueries(["likeStatus", post.id]);
      queryClient.invalidateQueries(["likeCnt", post.id]);
    },
  });

  const toggleLikes = () => {
    toggleLikehandler.mutate();
  };

  return {
    likeCnt: likesCnt,
    isLiked,
    toggleLikes,
    isLoading: toggleLikehandler.isLikeLoading,
  };
};

페이지네이션

export default function Pagination({ total, limit, page, setPage }) {
  //페이지 올림
  const numPages = Math.ceil(total / limit);

  return (
    <>
      <nav>
        <LeftButton onClick={() => setPage(page - 1)} disabled={page == 1}>
          &lt;
        </LeftButton>
        {Array(numPages)
          .fill()
          .map((v, i) => (
            <Button
              key={i + 1}
              onClick={() => setPage(i + 1)}
              aria-current={page === i + 1 ? "page" : null}
            >
              {i + 1}
            </Button>
          ))}
        <RightButton
          onClick={() => setPage(page + 1)}
          disabled={page === numPages}
        >
          &gt;
        </RightButton>
      </nav>
    </>
  );
}

구현이미지

좋아요

화면 기록 2024-07-31 17 05 14

페이지네이션

화면 기록 2024-07-31 17 04 33

게시물 신고

화면 기록 2024-07-31 17 08 52

jihyun132 commented 3 months ago

수고하셨습니다!