Chingu 팀 프로젝트를 하며 배운 것을 정리한다.
나는 React로 리액트 쿼리를 사용한 적이 있다.
이번 NextJs를 사용하는 프로젝트에도 공식 문서의 퀵 스타트 파트에 나와있는 튜토리얼을 그대로 따라서 데이터를 fetch했다.
그리고 풀 리퀘스트에서 팀원이 나에게 이런 피드백을 해줬다.
Next.js의 리액트 쿼리 hydration method를 사용한다고 한다.
Next.js를 사용해 본 적이 없어서 문서를 읽어도 뭐가 뭔지 모르겠음..🤔 아무튼 공식 문서에 있는 내용들을 보고 정리하려고 한다.
Next.js에서 리액트 쿼리를 사용할 때 queryClient에 데이터를 전달하는 방법으로 2가지가 있다.
하나는 initialData
를 통해 데이터를 직접 전달하는 것과 Hydration
을 통해 전달하는 방법이 있다.
= Next.js의 웹페이지 구성 원리
1. 서버 사이드 단에서 미리 웹페이지를 pre-rendering 한다.
2. 자바스크립트 요소들이 없는 HTML document가 생성된다. 이를 클라이언트에게 전송한다.
3. 서버에서 리액트가 번들링 된 자바스크립트 코드들을 클라이언트에게 전송한다.
4. 자바스크립트 코드들이 이전에 전송된 HTML DOM 위에 한번 더 렌더링을 하면서, 자기 자리를 찾아감.
자바스크립트 코드들이 DOM 요소 위에 물을 부어서 요소들을 채워나가는 것 같다고 해서 Hydrate라고 한다.
추천
index.js
export async function getStaticProps() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(['posts', 10], () => fetchPosts(10))
return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
export async function getStaticProps() {
const queryClient = new QueryClient();
await queryClient.prefetchQuery("categories", getCategories);
//await queryClient.prefetchQuery("데이터이름", fetch func);
return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
}
_app.js
import React from 'react'
import { Hydrate, QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from '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>
)
}
import GlobalStyles from "../components/GlobalStyles";
import Layout from "../components/Layout";
import { Hydrate } from "react-query";
export default function MyApp({ Component, pageProps }) {
return (
<>
<GlobalStyles />
<Layout>
<Hydrate state={pageProps.dehydratedState}>
<Component {...pageProps} />
</Hydrate>
</Layout>
</>
);
}
hooks/usePosts/index.js
import ky from 'ky-universal'
import { useQuery } from 'react-query'
const fetchPosts = async (limit = 10) => {
const parsed = await ky('https://jsonplaceholder.typicode.com/posts').json()
const result = parsed.filter(x => x.id <= limit)
return result
}
const usePosts = limit => {
return useQuery(['posts', limit], () => fetchPosts(limit))
}
export { usePosts, fetchPosts }
import { useQuery } from "react-query";
import { MEALDB_BASE_PATH } from "../constants";
export async function getCategories() {
const data = await (
await fetch(`${MEALDB_BASE_PATH}/list.php?c=list`)
).json();
return data;
}
export default function useCategories() {
return useQuery("categories", getCategories);
}
React Query 한글 메뉴얼
공식 문서 - https://react-query.tanstack.com/examples/nextjs
리액트 쿼리 in nextjs - https://gingerkang.tistory.com/123
hydrate - https://helloinyong.tistory.com/315
ssg,ssr 차이점 - https://higher77.tistory.com/105