1. 문제 상황
- A탭 처음 로딩 시, 네트워크 > 데이터 패칭에 아무것도 없다 : 서버에서 데이터를 미리 받아와, 이 데이터를 Dehydrate하여 브라우저에 보내주었기 때문이다.
- 이 때, A탭을 로딩할 때 A,B,C탭에 필요한 모든 데이터를 병렬적으로 미리 받아온다.
- A탭 → B탭 이동 시 : 브라우저에서 새로운 데이터를 받아온다.
- B탭 → A탭 이동 시 : 브라우저에서 새로운 데이터를 받아온다.
- A탭 → B탭 이동 시 : 캐싱된 데이터를 활용한다.
- B탭 → A탭 이동 시 : 캐싱된 데이터를 활용한다.
- 그 이후로도 4,5번과 동일하다.
2. 해결 과정
1. 서버에서 받아온 데이터를 캐싱하여, 브라우저에 넘겨주지는 못하는 걸까?
// HydrationProvider.tsx
const getQueryClient = cache(() => new QueryClient());
서버단에서 실행이되는 HydrationProvider내부의 코드이다. 내부에서 QueryClient를 새로 생성을한다.
// QueryProvider.tsx
const queryClient = new QueryClient({
// ..
})
그리고, 브라우저에서 실행이 되는 QueryProvider이다. 모든 컴포넌트를 감싸고 있으며 모든 컴포넌트에 이 QueryClient를 뿌려주고, 각 컴포넌트에서는 이 QueryClient객체에 캐싱된 데이터를 활용하는 것이다.
이 두 QueryClient 객체가 다르기에 당연히 서버에서 받아온 데이터의 캐싱이 적용되지 않았다고 판단했다.
2. 그렇다면, 서버에서 만든 QueryClient를 브라우저에서 사용할 수 없을까?
📚 react-query Hydration, Dehydrate 딥다이브
Dehydrate : 나중에 hydrate될 수 있도록 정적인 데이터로 만든다. 서버에서 prefetch된 데이터를 클라이언트에 전달할 때 사용한다.
Hydrate : 이전에 dehydrate된 값을
cache에 넣는다.
- HydrationBoundary : 이전에 dehydrate된 값을 queryclient에 넣는다. 이 queryclient는 useQueryClient에 의해 리턴된다.
- useQueryClient : QueryClient를 return한다.
HydrationBoundary(서버에서 데이터 prefetch)에서도 QueryClient를 생성하고, QueryProvider(클라이언트에서 데이터 fetch)에서도 Queryclient를 생성하기에 당연하다. QueryClient를 공유하는 것이 아니다. HydrationBoundary에서 데이터를 prefetch 후, 이 데이터를 dehydrate하여 클라이언트에 전송하는 것이다. 이 데이터를 클라이언트의 queryClient에 캐싱해두는 것이다.
HydrationBoundaryadds a previously dehydrated state into thequeryClientthat would be returned byuseQueryClient().
HydrationBoundary는 dehydrate된 상태를 queryClient에 추가합니다.
3. 실제 서버에 전송한 게 맞을까?
착각이었다. 위의 영상에서 받아온 데이터는 서버로부터 받아온 데이터가 아니라, 클라이언트에서 html을 받아오는 거였다.
이 말은 즉슨, 처음 Next.js서버에서 백엔드 서버에 데이터를 패칭한 후, 데이터는 캐싱되어 더이상 일어나지 않았다는 말이다.
❓ 그럼, 탭을 이동할 때 받아오는 이 데이터들은 뭘까?
rsc=라고 써있는 것을 보니, React server Component와 관련이 있는 듯하다.Next.js서버에서 렌더링한 RSC인데, 아직 보여주지 않아도 되어 보여주지 않다가(Lazy Loading) 해당 컴포넌트를 보여줘야할 때 Next.js서버에 요청하여 받아온 것이 아닐까?라고 추측한다.
![]()
![]()
형식이, RSC이다. Server에서 미리 렌더링하여, 이를 직렬화하여 전송한 듯하다.
3. 결론
HydrationProvider를 사용하여, Next.js 서버단에서 prefetching한 데이터를 dehydrate하여 브라우저에 보내준다. 이 캐싱된 데이터를 브라우저단에서도 활용하고 있다. Next.js서버에 요청하는 것을 백엔드 서버에 요청하는 것으로 착각했던 것이었다.