Skip to content

Commit b7ffbac

Browse files
committed
feat: 롤링페이퍼 무한 스크롤 적용
1 parent bf057d2 commit b7ffbac

File tree

2 files changed

+40
-28
lines changed

2 files changed

+40
-28
lines changed

src/apis/rolling.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,18 @@ export const getCurrentRollingPaper = async (): Promise<RollingPaperInformation>
99

1010
export const getRollingPaperDetail = async (
1111
rollingPaperId: string | number,
12+
page: number,
13+
size: number,
1214
): Promise<RollingPaper> => {
1315
const {
1416
data: { data },
15-
} = await client.get(`/api/event-posts/${rollingPaperId}`);
17+
} = await client.get(`/api/event-posts/${rollingPaperId}`, {
18+
params: {
19+
page,
20+
size,
21+
},
22+
});
23+
console.log(data);
1624
return data;
1725
};
1826

src/pages/RollingPaper/index.tsx

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { MasonryInfiniteGrid } from '@egjs/react-infinitegrid';
2-
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
3-
import { useState } from 'react';
2+
import { useMutation, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
3+
import { useState, useCallback } from 'react';
44
import { useParams } from 'react-router';
55

66
import { deleteRollingPaperComment, getRollingPaperDetail } from '@/apis/rolling';
@@ -14,6 +14,8 @@ import CommentDetailModal from './components/CommentDetailModal';
1414
import WriteCommentButton from './components/WriteCommentButton';
1515
import useAuthStore from '@/stores/authStore';
1616

17+
const MESSAGE_SIZE = 10;
18+
1719
const RollingPaperPage = () => {
1820
const id = useParams().id ?? '';
1921
const [activeComment, setActiveComment] = useState<RollingPaperComment | null>(null);
@@ -22,35 +24,36 @@ const RollingPaperPage = () => {
2224
const zipCode = useAuthStore((props) => props.zipCode);
2325
const queryClient = useQueryClient();
2426

25-
const { data, isSuccess } = useQuery({
27+
const { data, isSuccess, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({
2628
queryKey: ['rolling-paper', id],
27-
queryFn: () => getRollingPaperDetail(id),
29+
queryFn: ({ pageParam = 1 }) => getRollingPaperDetail(id, pageParam, MESSAGE_SIZE),
30+
getNextPageParam: (lastPage) => {
31+
const { currentPage, totalPages } = lastPage.eventPostComments;
32+
return currentPage < totalPages ? currentPage + 1 : undefined;
33+
},
34+
initialPageParam: 1,
2835
});
2936

3037
const { mutate: deleteComment } = useMutation({
3138
mutationFn: (rollingPaperId: number | string) => deleteRollingPaperComment(rollingPaperId),
32-
onSuccess: (data) => {
33-
queryClient.setQueryData(['rolling-paper', id], (oldData: RollingPaper) => {
34-
if (!oldData) return oldData;
35-
36-
return {
37-
...oldData,
38-
eventPostComments: {
39-
content: oldData.eventPostComments.content.filter(
40-
(comment: RollingPaperComment) => comment.commentId !== data.commentId,
41-
),
42-
},
43-
};
44-
});
45-
39+
onSuccess: () => {
40+
queryClient.invalidateQueries({ queryKey: ['rolling-paper', id] });
4641
setActiveDeleteModal(false);
4742
setActiveComment(null);
4843
},
49-
onError: (err) => {
50-
console.error(err);
44+
onError: () => {
45+
alert('편지 삭제에 실패했어요. 다시 시도해주세요');
5146
},
5247
});
5348

49+
const handleLoadMore = useCallback(() => {
50+
if (!isFetchingNextPage && hasNextPage) fetchNextPage();
51+
}, [fetchNextPage, hasNextPage, isFetchingNextPage]);
52+
53+
const allComments = data?.pages.flatMap((page) => page.eventPostComments.content) || [];
54+
const totalComments = data?.pages[0]?.eventPostComments.totalElements || 0;
55+
const title = data?.pages[0]?.title || '';
56+
5457
return (
5558
<>
5659
{activeDetailModal && activeComment && (
@@ -84,14 +87,12 @@ const RollingPaperPage = () => {
8487
)}
8588
<Header />
8689
<main className="flex grow flex-col items-center px-5 pt-20 pb-12">
87-
<PageTitle className="mb-18 max-w-73 text-center">{data?.title}</PageTitle>
88-
<p className="body-sb text-gray-60 mb-2 w-full">
89-
등록된 편지 {data ? data.eventPostComments.content.length : 0}
90-
</p>
90+
<PageTitle className="mb-18 max-w-73 text-center">{title}</PageTitle>
91+
<p className="body-sb text-gray-60 mb-2 w-full">등록된 편지 {totalComments}</p>
9192
<section className="w-full">
92-
<MasonryInfiniteGrid column={2} align="stretch" gap={16}>
93+
<MasonryInfiniteGrid column={2} align="stretch" gap={16} onRequestAppend={handleLoadMore}>
9394
{isSuccess &&
94-
data.eventPostComments.content.map((comment) => (
95+
allComments.map((comment) => (
9596
<Comment
9697
key={comment.commentId}
9798
comment={comment}
@@ -102,13 +103,16 @@ const RollingPaperPage = () => {
102103
/>
103104
))}
104105
</MasonryInfiniteGrid>
105-
{isSuccess && data.eventPostComments.content.length === 0 && (
106+
{isSuccess && allComments.length === 0 && (
106107
<p className="body-sb text-gray-60 my-20 text-center">
107108
아직 등록된 편지가 없어요.
108109
<br />
109110
첫번째로 편지를 남겨볼까요?
110111
</p>
111112
)}
113+
{isFetchingNextPage && (
114+
<p className="body-sb text-gray-60 my-4 text-center">Loading...</p>
115+
)}
112116
</section>
113117
<WriteCommentButton rollingPaperId={id} />
114118
</main>

0 commit comments

Comments
 (0)