이번 포스트에서는 Tanstack-Query의 useInfinityQuery hook사용에 대해 작성해보고자 한다.
먼저, 구현된 화면 UI는 다음과 같다.
프로젝트 아이템을 한 화면에서 9개까지 보여주고 있음을 확인할 수 있다.
만약 100개의 프로젝트 아이템이 있다고 가정해보자.
한 화면에 나올 아이템은 9개인데, 실제 저장된 데이터는 100개이면, 로딩 및 랜더링에 시간이 더 오래 걸릴 것이다.
따라서, 100개의 데이터중 9개만 우선적으로 갖고오고, 나머지는 useInfinity hook을 사용하여 9개씩 불러오도록 하였다.
먼저 사용자의 프로젝트 아이템을 불러오는 api 코드는 다음과 같다.
import api from '@/api/login/api';
import { getTokens } from '@/utils/Tokens';
export type videoArchiveType = {
id: number;
projectId: number;
jobId: string;
type: string;
status: string;
retryCount: number;
createdAt: string;
updatedAt: string;
};
export const getVideoArchive = async () => {
const { accessToken } = getTokens();
try {
const response = await api.get('/api/v1/tasks', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
return response.data;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
위 코드에서는 9개 처리에 대한 코드가 구현되어 있지 않다.
useInfinity hook에 대한 값을 설정할 때 작성한다.
사용법은 https://vitamin3000.tistory.com/207를 참조하기 바란다.
TanStackQuery (11) - 페이지별, 무한 스크롤 쿼리 적용
이번 포스트에서는 지난 포스트에서 학습한 페이지별, 무한 스크롤을 실제로 적용해보고자 한다. QueryClientProvider로 최상위 컴포넌트를 감싸야 한다.왜? -> 이것을 통해 React Query의 전역 상태를
vitamin3000.tistory.com
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
isLoading,
error,
refetch,
} = useInfiniteQuery({
queryKey: ['projects', activeTab],
queryFn: ({ pageParam = 0 }) => getProjects(pageParam, 9),
getNextPageParam: (lastPage, allPages) => {
const nextOffset = allPages.length * 9;
return lastPage.hasMore ? nextOffset : undefined;
},
initialPageParam: 0,
});
useEffect(() => {
refetch();
}, [activeTab, refetch]);
const handleObserver = useCallback(
(entries: IntersectionObserverEntry[]) => {
const [entry] = entries;
if (entry.isIntersecting && hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
},
[fetchNextPage, hasNextPage, isFetchingNextPage]
);
useEffect(() => {
const observer = new IntersectionObserver(handleObserver, {
threshold: 0.1,
});
const currentTarget = observerTarget.current;
if (currentTarget) {
observer.observe(currentTarget);
}
return () => {
if (currentTarget) {
observer.unobserve(currentTarget);
}
};
}, [handleObserver]);
이때 로딩 스피너는 다음과 같이 구현하였다.
type LoadingSpinnerProps = {
text: string;
showText: boolean;
}
const LoadingSpinner = ({
text = '로딩 중...',
showText = true,
}: LoadingSpinnerProps) => {
return (
<Container>
<SpinnerWrapper />
{showText && <Text>{text}</Text>}
</Container>
);
};
작성한 애니메이션은 다음과 같다. 뱅글뱅글 돈다
// 회전 애니메이션 정의
const spin = keyframes`
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
`;
'패스트캠퍼스 데브캠프' 카테고리의 다른 글
파이널 프로젝트 - (9) aws CloudFront https 배포 (0) | 2025.04.04 |
---|---|
파이널 프로젝트 - (8) aws s3 정적 배포 (0) | 2025.04.04 |
파이널 프로젝트 - 회원가입 (6) - 로그인 (0) | 2025.04.04 |
파이널 프로젝트 - 회원가입 (6) - 카카오/구글 로그인 (0) | 2025.04.04 |
파이널 프로젝트 - 회원가입 (5) - 이메일 인증 (0) | 2025.04.03 |