next에서 리액트쿼리를 세팅하면서 타입을 어떻게 세팅해야 할지 막막해서 알아보았다.
next에서는 원래 swr를 제공하는데, 이번엔 react query랑 recoil을 조합해서 써보려고 한다.
커스터마이징을 하려면 _app
, _document
파일을 만들어서 세팅해야한다.
_app
은 next의 최상위 컴포넌트이다.모든 페이지에 공통적으로 적용되는 것들을 여기서 처리한다.
레이아웃, 상태관리, 글로벌 css등을 여기서 세팅하면 된다.
next/app 에서 필요한 요소들을 import해와서 커스텀한다.
_document
가 그것인데, 서버 사이드 렌더링을 위해서 사용한다. head 섹션에 메타 태그를 추가하거나 외부 스타일시트를 로드한다.
next/document 에서 필요한 요소들을 import해와서 커스텀한다.
_app
,_document
두 파일 모두 pages 폴더 아래 위치해야 한다.
_app.js에서 리액트쿼리를 세팅하는 코드임.
import React from "react";
import {
Hydrate,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
export default function MyApp({
Component,
pageProps,
}) {
const [queryClient] = React.useState(() => new QueryClient());
return (
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<Component {...pageProps} />
</Hydrate>
<ReactQueryDevtools />
</QueryClientProvider>
);
}
타입스크립트로 하다보니 props(Component, pageProps) 부분에서 타입에러가 발생했다.
import React from "react";
import {
DehydratedState,
Hydrate,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
import type { NextPageContext } from "next";
import type { AppProps } from "next/app";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
type PageProps = {
dehydratedState?: DehydratedState;
};
type ExtendedAppProps<P = {}> = {
err?: NextPageContext["err"];
} & AppProps<P>;
export default function MyApp({
Component,
pageProps,
}: ExtendedAppProps<PageProps>) {
const [queryClient] = React.useState(() => new QueryClient());
return (
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<Component {...pageProps} />
</Hydrate>
<ReactQueryDevtools />
</QueryClientProvider>
);
}
넥스트로 세번째 프로젝트를 해보는건데,,, 할때마다 새롭다.
ssr을 할 때, 초기 렌더링이 서버에서 이루어진다.
이후 유저와 상호작용하면서 상태가 바뀌게 된다.
이 과정에서 hydrate를 사용해 클라이언트에서 상태가 바뀌면서 렌더링된 컴포넌트
와 서버에서 렌더링된 컴포넌트
를 동기화시키는 것이다.
클라이언트에서 ReactDom.hydrate를 호출하면 클라이언트에서 서버와 동기화(업데이트)한다.
next.js에서는 페이지를 서버에서 최초 렌더링 한 후에 클라이언트에 전송한다.
클라이언트에서는 ReactDom.hydrate 대신 hydrate 함수를 실행해 이 초기 렌더링을 동기화한다.
클라이언트에서 렌더링된 컴포넌트, 서버에서 렌더링된 컴포넌트를 일치시킨다.
서버 사이드 렌더링의 이점(빠른 로딩, seo) + 클라이언트에서의 동적 동작(상호작용, 이벤트 처리)
을 위한 것이다.