diff --git a/public/spinner.svg b/public/spinner.svg new file mode 100644 index 00000000..f65e5227 --- /dev/null +++ b/public/spinner.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/apis/getRecentEpigrams.ts b/src/apis/getRecentEpigrams.ts index a2fb9f52..04db411a 100644 --- a/src/apis/getRecentEpigrams.ts +++ b/src/apis/getRecentEpigrams.ts @@ -1,9 +1,10 @@ import type { GetRecentEpigramsResponseType } from '@/schema/recentEpigram'; import httpClient from './index'; -const getRecentEpigrams = async (limit: number): Promise => { +const getRecentEpigrams = async (cursor: number | null, limit: number): Promise => { const response = await httpClient.get('/epigrams', { params: { + cursor, limit, }, }); diff --git a/src/components/main/RecentEpigram.tsx b/src/components/main/RecentEpigram.tsx index 4fb4d1eb..ce77e43e 100644 --- a/src/components/main/RecentEpigram.tsx +++ b/src/components/main/RecentEpigram.tsx @@ -1,31 +1,52 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import useGetRecentEpigrams from '@/hooks/useGetRecentEpigrams'; import EpigramCard from '@/components/Card/EpigramCard'; import { RecentEpigramType } from '@/schema/recentEpigram'; +import Image from 'next/image'; import LoadMoreButton from './LoadMoreButton'; +import spinner from '../../../public/spinner.svg'; function RecentEpigrams() { const router = useRouter(); - const [limit, setLimit] = useState(3); - const { data, error, isLoading } = useGetRecentEpigrams(limit); + const [epigrams, setEpigrams] = useState([]); + const [cursor, setCursor] = useState(0); + const [limit, setLimit] = useState(3); // Initial limit is 3 + const [isLoadingMore, setIsLoadingMore] = useState(false); + const [shouldFetch, setShouldFetch] = useState(true); // Trigger fetching manually + + const { data, error, isLoading } = useGetRecentEpigrams({ cursor, limit, enabled: shouldFetch }); + + useEffect(() => { + if (data) { + setEpigrams((prevEpigrams) => [...prevEpigrams, ...data.list]); // Append new data to the existing list + if (data.list.length > 0) { + // Update cursor to the ID of the last item in the current list + setCursor(data.list[data.list.length - 1].id); + } + setIsLoadingMore(false); // Ensure loading stops when data is fetched + setShouldFetch(false); // Reset fetch trigger after fetching + } + }, [data]); const handleEpigramClick = (id: number) => { router.push(`/epigrams/${id}`); }; const loadMore = () => { - setLimit((prevLimit) => prevLimit + 5); + setIsLoadingMore(true); // Set loading state + setLimit(5); // After initial load, always fetch 5 items + setShouldFetch(true); // Trigger fetch }; - if (isLoading) return

로딩 중...

; + if (isLoading && epigrams.length === 0) return

로딩 중...

; if (error) return

{error.message}

; return (

최신 에피그램

- {data?.list.map((epigram: RecentEpigramType) => ( + {epigrams.map((epigram: RecentEpigramType) => (
handleEpigramClick(epigram.id)} @@ -40,7 +61,12 @@ function RecentEpigrams() {
))} - {data && limit < data.totalCount && ( + {isLoadingMore && ( +
+ 로딩중 +
+ )} + {!isLoadingMore && data?.nextCursor !== null && (
diff --git a/src/hooks/useGetRecentEpigrams.ts b/src/hooks/useGetRecentEpigrams.ts index beaaa314..19f862f9 100644 --- a/src/hooks/useGetRecentEpigrams.ts +++ b/src/hooks/useGetRecentEpigrams.ts @@ -2,10 +2,11 @@ import { useQuery } from '@tanstack/react-query'; import getRecentEpigrams from '@/apis/getRecentEpigrams'; import { GetRecentEpigramsResponseType } from '@/schema/recentEpigram'; -const useGetRecentEpigrams = (limit: number) => +const useGetRecentEpigrams = ({ cursor, limit, enabled }: { cursor: number | null; limit: number; enabled: boolean }) => useQuery({ - queryKey: ['recentEpigrams', limit], - queryFn: () => getRecentEpigrams(limit), + queryKey: ['recentEpigrams', cursor, limit], + queryFn: () => getRecentEpigrams(cursor, limit), + enabled, }); export default useGetRecentEpigrams; diff --git a/src/schema/recentEpigram.ts b/src/schema/recentEpigram.ts index 899fcc7f..fe664e60 100644 --- a/src/schema/recentEpigram.ts +++ b/src/schema/recentEpigram.ts @@ -18,7 +18,7 @@ const RecentEpigramSchema = z.object({ export const GetRecentEpigramsResponseSchema = z.object({ totalCount: z.number(), - nextCursor: z.number(), + nextCursor: z.number().nullable(), list: z.array(RecentEpigramSchema), });