1. 문제 상황

Untitled

  1. A탭 처음 로딩 시, 네트워크 > 데이터 패칭에 아무것도 없다 : 서버에서 데이터를 미리 받아와, 이 데이터를 Dehydrate하여 브라우저에 보내주었기 때문이다.
  2. A탭 → B탭 이동 시 : 브라우저에서 새로운 데이터를 받아온다.
  3. B탭 → A탭 이동 시 : 브라우저에서 새로운 데이터를 받아온다.
  4. A탭 → B탭 이동 시 : 캐싱된 데이터를 활용한다.
  5. B탭 → A탭 이동 시 : 캐싱된 데이터를 활용한다.

2. 해결 과정

1. 서버에서 받아온 데이터를 캐싱하여, 브라우저에 넘겨주지는 못하는 걸까?

// HydrationProvider.tsx
const getQueryClient = cache(() => new QueryClient());

서버단에서 실행이되는 HydrationProvider내부의 코드이다. 내부에서 QueryClient를 새로 생성을한다.

// QueryProvider.tsx
const queryClient = new QueryClient({
  // ..
})

그리고, 브라우저에서 실행이 되는 QueryProvider이다. 모든 컴포넌트를 감싸고 있으며 모든 컴포넌트에 이 QueryClient를 뿌려주고, 각 컴포넌트에서는 이 QueryClient객체에 캐싱된 데이터를 활용하는 것이다.

이 두 QueryClient 객체가 다르기에 당연히 서버에서 받아온 데이터의 캐싱이 적용되지 않았다고 판단했다.

2. 그렇다면, 서버에서 만든 QueryClient를 브라우저에서 사용할 수 없을까?

<aside> 📚 react-query Hydration, Dehydrate 딥다이브

Dehydrate : 나중에 hydrate될 수 있도록 정적인 데이터로 만든다. 서버에서 prefetch된 데이터를 클라이언트에 전달할 때 사용한다.

Hydrate : 이전에 dehydrate된 값을 cache에 넣는다.

HydrationBoundary(서버에서 데이터 prefetch)에서도 QueryClient를 생성하고, QueryProvider(클라이언트에서 데이터 fetch)에서도 Queryclient를 생성하기에 당연하다. QueryClient를 공유하는 것이 아니다. HydrationBoundary에서 데이터를 prefetch 후, 이 데이터를 dehydrate하여 클라이언트에 전송하는 것이다. 이 데이터를 클라이언트의 queryClient에 캐싱해두는 것이다.