RSC에서 react-query를 사용하는 방법

우선 이해하기 쉽게 코드로 바로 알아보자.

// app/getQueryClient.ts
import {
defaultShouldDehydrateQuery,
isServer,
QueryClient,
} from "@tanstack/react-query";

  

function makeQueryClient() {
	return new QueryClient({
		defaultOptions: {
			queries: {
				// SSR에서 기본적으로 사용하는 staleTime
				// client에서 바로 재요청을 막기 위해서 0보다 높은 값으로 설정한다.
				staleTime: 60 * 1000
			},
			dehydrate: {
				shouldDehydrateQuery: (query) =>
					defaultShouldDehydrateQuery(query) || query.state.status === "pending",
			},
		},
	});
}
let browserQueryClient: QueryClient | undefined = undefined;

export function getQueryClient() {
if (isServer) {
	// 서버에서는 항상 queryClient를 생성한다.
	return makeQueryClient();
} else {
	// 브라우저에서는 queryClient가 없는 경우에만 새 queryClient를 만든다.
	// queryClient는 매우 중요하므로 초기 렌더링 중에 React가 일시 중단되는 경우 새 클라이언트를 만들지 않는다. queryClient 생성 아래에 서스펜스 경계가 있는 경우 이 작업이 필요하지 않을 수 있다.
	if (!browserQueryClient) browserQueryClient = makeQueryClient();
		return browserQueryClient;
	}
}

우선 queryClient를 서버와 클라이언트 각각 생성한다. 만약 서버 컴포넌트에서 getQueryClient() 함수를 호출하면 queryClient를 새로 생성하고

서버 컴포넌트에서 React-query를 사용하기 전에 prefetchQuery에 대한 이해가 필요하다. prefetchQuery란, 특정 데이터가 필요할 것으로 예상되는 경우 프리페칭을 사용하여 캐시를 해당 데이터로 미리 채우는 것으로 더욱 빠른 사용자 경험을 제공할 수 있다.

prefetchQuery 및 prefetchInfiniteQuery

  • 이 함수들은 queryClient에 대해 구성된 기본 staleTime을 사용하여 캐시에 있는 기존 데이터가 최신 데이터인지 또는 다시 가져와야할 데이터인지 여부를 결정한다.
  • 해당 함수에서도 staleTime 옵션을 줄 수 있으며 다음과 같은 특징을 가진다.
  • 만약 서버에서 prefetch한 쿼리에 대해 useQuery 인스턴스가 나타나지 않으면 gcTime에 지정된 시간 후에 쿼리가 삭제되고 가비지 수집된다.
  • 이 함수는 Promise를 반환하므로 쿼리 데이터를 반환하지 않는다. 이러한 기능이 필요하다면 fetchQuery/fetchInfinteQuery를 사용해야한다.
  • prefetch 함수는 일반적으로 useQuery에서 다시 가져오기를 시도하기 때문에 오류가 발생하지 않는다. 오류를 잡아야하는 경우 대신 fetchQuery/fetchInfinteQuery를 사용해야한다.
  • Usage