Prefetching
Prefetching은 데이터가 실제로 필요하기 전에 사전에 데이터를 가져오고 캐시에 저장하는 프로세스를 말한다.
이를 통해 데이터를 미리 가져올 수 있으며, 필요할 때 데이터를 즉시 사용할 수 있다. 이는 애플리케이션의 응답성과 사용자 경험을 개선시킨다. TanStack Query에서는 prefetchQuery로 이를 구현할 수 있다.
prefetchQuery
prefetchQuery는 TanStack Query에서 제공하는 API 중 하나로, 사용자가 지정한 키와 옵션을 통해 데이터를 미리 가져와 캐싱한다. 이렇게 하면 해당 데이터를 사용하는 페이지나 컴포넌트가 로드될 때 즉시 데이터를 사용할 수 있어 사용자 경험이 향상된다.
prefetchQuery의 주요 특징
A. 데이터 미리 가져오기 : 컴포넌트가 마운트되기 전에 데이터를 로드하고 캐싱한다.
B. 사용자 경험 개선 : 초기 로딩 시간을 줄이고, 빠른 화면 전환을 제공한다.
C. 백그라운드 데이터 로딩 : 현재 화면에 표시되지 않는 데이터를 백그라운드에서 미리 가져와 준비한다.
D. 캐시 재사용 : 동일한 쿼리 키로 데이터를 요청할 경우 캐시된 데이터를 사용한다.
라우팅 전 데이터 미리 가져오기
// hooks/usePostDetail.js
import { useQuery } from '@tanstack/react-query';
import { fetchPostDetail } from '../api/posts';
export const usePostDetail = (postId) => {
return useQuery({
queryKey: ['postDetail', postId],
queryFn: () => fetchPostDetail(postId),
});
};
export const usePrefetchPostDetail = () => {
const queryClient = useQueryClient();
const prefetchPostDetail = (postId) => {
queryClient.prefetchQuery({
queryKey: ['postDetail', postId],
queryFn: () => fetchPostDetail(postId),
});
};
return prefetchPostDetail;
};
// components/PostsList.js
import React from 'react';
import { Link } from 'react-router-dom';
import { posts } from '../posts';
import { usePrefetchPostDetail } from '../hooks/usePrefetchPostDetail';
const PostsList = () => {
const prefetchPostDetail = usePrefetchPostDetail();
return (
<ul>
{posts.map((post) => (
<li
key={post.id}
onMouseEnter={() => prefetchPostDetail(post.id)}
>
<Link to={`/posts/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
);
}
export default PostsList;
// components/PostDetail.js
import { useParams } from 'react-router-dom';
import { usePostDetail } from '../hooks/usePostDetail';
const PostDetail = () => {
const { id } = useParams();
const { data } = usePostDetail(id);
return (
<div>
<h1>{data.title}</h1>
<p>{data.content}</p>
</div>
);
}
export default PostDetail;
페이지네이션에서 다음 페이지 미리 가져오기
// hooks/usePostList.js
import { useQuery } from '@tanstack/react-query';
import { fetchPostList } from '../api/posts';
export const usePostList = (page) => {
return useQuery({
queryKey: ['postList', page],
queryFn: () => fetchPostLists(page),
});
};
export const usePrefetchPostList = () => {
const queryClient = useQueryClient();
const prefetchPostList = (page) => {
queryClient.prefetchQuery({
queryKey: ['postList', page],
queryFn: () => fetchPostLists(page),
});
};
return prefetchPostList;
};
// components/Table.js
import React, { useEffect } from 'react';
import { usePageData } from '../hooks/usePageData';
import { usePrefetchPageData } from '../hooks/usePrefetchPageData';
const Table = () => {
const [currentPage, setCurrentPage] = React.useState(1);
const { data } = usePostList(currentPage);
const prefetchPageData = usePrefetchPageData();
useEffect(() => {
prefetchPageData(currentPage + 1);
}, [currentPage]);
return (
<div>
<table>
{... Post List}
</table>
<div>
<button onClick={() => setCurrentPage((prev) => prev - 1)}>
이전 페이지
</button>
<button onClick={() => setCurrentPage((prev) => prev + 1)}>
다음 페이지
</button>
</div>
</div>
);
}
export default Table;