지난 미니 프로젝트에서 만들었던 MBTICOLOR 프로젝트에서 적용해보지 못했던 기능들이 있어 이들을 적용을 해보았다.
바로 스켈레톤 UI와 로딩 스피너이다.
데이터를 불러오는 동안, 실제 콘텐츠가 로드되기 전 자리 표시자(플레이스홀더)로 회색 블록이나 모형 형태로 화면을 먼저 채워주는 UI 방식이다. 사용자가 페이지가 로드되는 동안 빈 공간 대신 콘텐츠의 구조를 미리 파악할 수 있도록 돕는다.
떠라서 사용자의 경험을 전보다 개선시켜줄 수 있다는 장점을 가지고 있다.
서버로부터 데이터를 요청하거나 작업을 처리하는 동안 화면에 회전하는 아이콘(보통 원형의 회전 애니메이션)을 표시하여 사용자가 시스템이 작업 중임을 알 수 있게 한다. 로딩 중이라는 사실을 명확하게 시각적으로 표현해준다.
우선 Skeleton UI를 적용시키기 위한 컴포넌트를 하나 만들었다.
해당 페이지의 각 카드 디자인에 맞게 구성시켰다.
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useInfiniteQuery<ColorSurvey>({
queryKey: ['getColorSurveys', filterMbti],
queryFn: ({ pageParam = 0 }: any) => getColorSurvey(filterMbti || undefined, 12, pageParam), // offset을 pageParam * 10으로 설정
getNextPageParam: (lastPage, allPages) => {
// 현재 페이지 수
const currentPage = allPages.length;
// 다음 페이지의 offset 계산 (10씩 더하기)
return currentPage < lastPage.count / 12 ? currentPage : undefined;
},
initialPageParam: 0, // 초기 페이지 파라미터 설정
});
위의 페이지에서 데이터를 불러오는 코드인데 이때 useInfiniteQuery에서 isLoading 값을 가져와 참인 경우 Skeleton UI를 적용시켜주었다.
{isLoading
? [...Array(12)].map(() => <SkeletonLoader />) // 데이터 로딩 중 SkeletonLoader 보여줌
:....
또한 로딩 스피너는 리액트에서 제공하는
react-spinners
라이브러리를 사용하였고
마찬가지로 위의 isFetchingNextPage를 가져와 다음 페이지를 패칭하고 있을때 로딩 스피너를 보여주도록 하였다.
{isFetchingNextPage && (
<div className="flex w-[100%] justify-center items-center mt-4">
<CircleLoader color="#3498db" size={50} aria-label="Loading Spinner" data-testid="loader" />
</div>
)}