게시판 목록 데이터를 keepPreviousData
기능을 활용하기 위해 TanStack Query
로 불러오고 있습니다.
하지만 현재는 TanStack Query
가 CSR로만 동작하기 때문에, 첫 로딩 시 데이터가 없어 화면이 잠깐 깜빡이는 문제가 발생했습니다.
// query-provider.tsx
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
},
},
})
}
let browserQueryClient: QueryClient | undefined = undefined
export function getQueryClient() {
if (isServer) {
return makeQueryClient()
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient()
return browserQueryClient
}
}
// query-provider.tsx
'use client'
import { getQueryClient } from './queryClient';
import {
isServer,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'
export default function Providers({ children }: { children: React.ReactNode }) {
const queryClient = getQueryClient()
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}
서버는 매 요청마다 새로 만들고, 브라우저는 전역에 한 번 만들어 재사용합니다. SSR 직후 불필요한 재요청을 막기 위해 staleTime
을 60초로 둡니다.
QueryClient
생성할까?서버는 한 번에 여러 사람의 요청을 처리합니다.
만약 서버에서 만든 하나의 QueryClient
를 계속 재사용한다면, 사용자 A가 불러온 데이터가 그대로 남아 있다가 사용자 B에게도 섞여서 보일 수 있습니다.
예를 들어,
따라서 서버에서는 요청마다 새로운 QueryClient를 만들어서 사용자별로 완전히 분리합니다.
QueryClient
를 전역으로 저장할까?브라우저에서 QueryClient
를 계속 새로 만들면 캐시가 초기화되어 매번 데이터를 다시 불러오게 됩니다.
따라서 한 번 만든 인스턴스를 전역 변수에 저장해두고 계속 재사용합니다.
staleTime
을 0보다 크게 줄까?기본값 staleTime: 0
이면 SSR로 받은 데이터도 즉시 만료로 간주되어 하이드레이션 직후 재요청합니다.
따라서 staleTime
을 60초 정도로 설정해 하이드레이션 이후에는 불필요한 재요청이 일어나지 않도록 합니다.
// page.tsx
export default async function Page({ params }: { params: Promise<{ boardId: string }> }) {
const queryClient = getQueryClient();
const { boardId } = await params;
await queryClient.prefetchQuery({
queryKey: ['posts', Number(boardId), 1],
queryFn: () => axiosPosts(Number(boardId), 1, BOARD_PAGE_SIZE),
});
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Board boardId={Number(boardId)} />
</HydrationBoundary>
);
}
QueryClient
를 생성한다.queryClient.prefetchQuery
로 필요한 데이터를 미리 불러와 캐시에 담는다.dehydrate(queryClient)
로 직렬화된 캐시 상태를 만든다.HydrationBoundary
로 감싸 클라이언트 컴포넌트에 전달한다.SSR을 적용한 이후에는 첫 화면 로딩 시 깜빡임 현상이 사라졌습니다.
그 결과, 사용자 경험(UX)이 한층 향상되었습니다.