Skip to content

Commit

Permalink
feat: 댓글 무한 스크롤 조회 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
semnil5202 committed Mar 7, 2024
1 parent ec698ef commit 3324b0e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
9 changes: 7 additions & 2 deletions src/pages/FeedDetail/components/Comments.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { Box, Divider } from 'concept-be-design-system';
import { Fragment } from 'react';
import { Fragment, useRef } from 'react';

import Comment from './Comment';
import WriteComment from './WriteComment';
import { useMemberInfoQuery } from '../../profile/hooks/queries/useMemberInfoQuery';
import useCommentsQuery from '../hooks/queries/useCommentsQuery';
import useCommentInfiniteFetch from '../hooks/useCommentInfiniteFetch';

interface Props {
feedId: string;
}

const Comments = ({ feedId }: Props) => {
const { comments } = useCommentsQuery(feedId);
const { comments, fetchNextPage } = useCommentsQuery(feedId);
const { profileImageUrl: myImageUrl, nickname: myNickname, skills: mySkillList } = useMemberInfoQuery();

const intersectionRef = useRef(null);
useCommentInfiniteFetch(intersectionRef, fetchNextPage);

return (
<Box padding="20px 22px">
<WriteComment feedId={feedId} myImageUrl={myImageUrl} myNickname={myNickname} />
Expand All @@ -29,6 +33,7 @@ const Comments = ({ feedId }: Props) => {
{idx !== comments.length - 1 ? <Divider color="l3" /> : <></>}
</Fragment>
))}
<div ref={intersectionRef}></div>
</Box>
);
};
Expand Down
24 changes: 19 additions & 5 deletions src/pages/FeedDetail/hooks/queries/useCommentsQuery.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { useSuspenseInfiniteQuery } from '@tanstack/react-query';

import { http } from '../../../../api/http';
import { CommentParentResponse } from '../../types';

const getComments = (feedId: string) => http.get<CommentParentResponse[]>(`/ideas/${feedId}/comments`);
interface GetCommentsProps {
page: number;
size: number;
}

const getComments = (feedId: string, { page, size }: GetCommentsProps) =>
http.get<CommentParentResponse[]>(`/ideas/${feedId}/comments?page=${page}&size=${size}`);

const useCommentsQuery = (feedId: string) => {
const { data: comments, ...rest } = useSuspenseQuery({
const sizePerPage = 10;
const { data, fetchNextPage, ...rest } = useSuspenseInfiniteQuery({
queryKey: ['comments', feedId],
queryFn: () => getComments(feedId),
initialPageParam: { page: 0, size: sizePerPage },
queryFn: ({ pageParam }) => getComments(feedId, pageParam),
getNextPageParam: (lastPage, allPages, lastPageParam) => {
const nextPageParam = { page: lastPageParam.page + 1, size: sizePerPage };

// 대댓글 또한 댓글로 간주되어 lastPage.length < sizePerPage 조건문이 정상적으로 동작하지 않아 제거했습니다.
return lastPage.length === 0 ? undefined : nextPageParam;
},
});

return { comments, ...rest };
return { comments: data.pages.flat(), fetchNextPage, ...rest };
};

export default useCommentsQuery;
18 changes: 18 additions & 0 deletions src/pages/FeedDetail/hooks/useCommentInfiniteFetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { MutableRefObject, useEffect } from 'react';
import { useIntersection } from 'react-use';

const useCommentInfiniteFetch = (intersectionRef: MutableRefObject<null>, fetchCallback: () => void) => {
const intersection = useIntersection(intersectionRef, {
root: null,
rootMargin: `0px`,
threshold: 1,
});

useEffect(() => {
if (intersection?.isIntersecting) {
fetchCallback();
}
}, [intersection, fetchCallback]);
};

export default useCommentInfiniteFetch;

0 comments on commit 3324b0e

Please sign in to comment.