getServerSideProps()
를 이용해서 클라이언트 서버단에서 data를 fetching하고, 그 데이터를 prefetching 하는 방법에 대해 알아본다. 이 방법을 사용하면, 최초 화면이 렌더링 될 때는 클라이언트 서버에서 data를 fetching 하기 때문에 API 서버와 통신하는 이력을 볼 수 없을 것이다. 이후 같은 query key의 데이터를 다시 fetching 하면 클라이언트에서 data를 fetching 한다. (해당 query가 stale 상태일 때)
Hydrate
이다. 공식문서에서 제시하는 방법대로 설정한다.
import "../styles/globals.css";
import type { AppProps } from "next/app";
import { Hydrate, QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
const queryClient = new QueryClient();
function MyApp({ Component, pageProps }: AppProps) {
return (
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}> // << 이 부분
<Component {...pageProps} />
<ReactQueryDevtools />
</Hydrate>
</QueryClientProvider>
);
}
export default MyApp;
Next.js
에서 SSR을 하기 위해서는 컴포넌트 파일 내에서 getServerSideProps()
를 사용한다. 해당 함수는 Next.js 클라이언트 서버
단에서 실행된다. 프로세스는 다음과 같다. [queryClient 생성] -> [queryClient에서 prefetchQeury()를 이용해서 data fetching] -> [props에서
dehydratedState: dehydrate(qc)
로 return] -> [컴포넌트 단에서 같은 query key로 useQuery()] -> [{data}를 활용해서 rendering]
export const getServerSideProps: GetServerSideProps = async (context) => {
const { id } = context.query;
const qc = new QueryClient();
await qc.prefetchQuery(
["person"],
async () => {
const { data } = await axios.get(`http://localhost:3001/person/${id}`);
return data;
}
);
return {
props: {
name: "with",
id,
dehydratedState: dehydrate(qc), // 반드시 dehydratedState 이어야 함
},
};
};
적용 후 컴포넌트를 Refresh 하면, 최초에 데이터 fetching이 network에 보이지 않는 것을 확인 할 수 있다. 클라이언트 서버단에서 데이터 fetching이 이루어 졌기 때문이다.
import axios from "axios";
import { GetServerSideProps } from "next";
import React from "react";
import { dehydrate, QueryClient, useQuery } from "react-query";
const Item = ({ id }: any) => {
const { data } = useQuery(
["person"],
async () => {
const { data } = await axios.get(`http://localhost:3001/person/${id}`);
return data;
},
{
staleTime: 3000,
}
);
return (
<div>
<div>{data?.name}</div>
<div>{data?.age}</div>
</div>
);
};
export const getServerSideProps: GetServerSideProps = async (context) => {
const { id } = context.query;
const qc = new QueryClient();
await qc.prefetchQuery(
["pers1on"],
async () => {
const { data } = await axios.get(`http://localhost:3001/person/${id}`);
return data;
},
{
staleTime: 10000,
}
);
return {
props: {
name: "with",
id,
dehydratedState: dehydrate(qc),
},
};
};
export default Item;