diff --git a/src/components/Tours/ToursItemSkeleton.tsx b/src/components/Tours/ToursItemSkeleton.tsx new file mode 100644 index 00000000..ca91d5d4 --- /dev/null +++ b/src/components/Tours/ToursItemSkeleton.tsx @@ -0,0 +1,16 @@ +const ToursItemSkeleton = () => { + return ( +
+
+
+
+

+
+
+
+
+
+ ); +}; + +export default ToursItemSkeleton; diff --git a/src/components/Tours/ToursList.tsx b/src/components/Tours/ToursList.tsx index 10a2f6cc..700c343f 100644 --- a/src/components/Tours/ToursList.tsx +++ b/src/components/Tours/ToursList.tsx @@ -1,26 +1,40 @@ import { TourType, ToursListProps } from '@/@types/tours.types'; -import ToursItem from './ToursItem'; import { getTours } from '@api/tours'; import { useInfiniteQuery } from '@tanstack/react-query'; +import React, { useEffect, useState } from 'react'; import InfiniteScroll from 'react-infinite-scroller'; -import React from 'react'; +import { v4 as uuidv4 } from 'uuid'; +import ToursItem from './ToursItem'; +import ToursItemSkeleton from './ToursItemSkeleton'; const ToursList = ({ selectedRegion }: ToursListProps) => { - const { fetchNextPage, hasNextPage, data, error } = useInfiniteQuery({ - queryKey: ['tours', selectedRegion], - queryFn: ({ pageParam = 0 }) => getTours(selectedRegion, pageParam, 10), - initialPageParam: 0, - getNextPageParam: (lastPage) => { - const currentPage = lastPage?.data.data.pageable.pageNumber; - const totalPages = lastPage?.data.data.totalPages; - - if (currentPage < totalPages - 1) { - return currentPage + 1; - } - - return undefined; - }, - }); + const { fetchNextPage, hasNextPage, data, isLoading, error } = + useInfiniteQuery({ + queryKey: ['tours', selectedRegion], + queryFn: ({ pageParam = 0 }) => getTours(selectedRegion, pageParam, 10), + initialPageParam: 0, + getNextPageParam: (lastPage) => { + const currentPage = lastPage?.data.data.pageable.pageNumber; + const totalPages = lastPage?.data.data.totalPages; + + if (currentPage < totalPages - 1) { + return currentPage + 1; + } + + return undefined; + }, + }); + + const [showSkeleton, setShowSkeleton] = useState(isLoading); + + useEffect(() => { + if (isLoading) { + setShowSkeleton(true); + } else { + const timer = setTimeout(() => setShowSkeleton(false), 200); + return () => clearTimeout(timer); + } + }, [isLoading]); if (error) { return
데이터를 불러오는 중 오류가 발생했습니다.
; @@ -32,18 +46,27 @@ const ToursList = ({ selectedRegion }: ToursListProps) => { loadMore={() => fetchNextPage()} hasMore={hasNextPage} loader={ -
- Loading ... +
+
+
Loading...
+
}> -
- {data?.pages.map((group, index) => ( - - {group?.data.data.content.map((tour: TourType) => ( - +
+ {showSkeleton + ? Array.from({ length: 10 }, (_, index) => ( + + )) + : data?.pages.map((group) => ( + + {group?.data.data.content.map((tour: TourType) => ( + + ))} + ))} - - ))}
);