[ํ”„๋กœ์ ํŠธ] Next.js_๐Ÿซ  3

ํ•จ๋ฏผํ˜ยท2023๋…„ 11์›” 7์ผ
0

ํ”„๋กœ์ ํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
10/18

React-Query + Next.js

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ๋ฆฌ์—‘ํŠธ ์ฟผ๋ฆฌ์™€ ๋„ฅ์ŠคํŠธ๋ฅผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์—‘ํŠธ์ฟผ๋ฆฌ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.

โœ… SSR, SSG

react-query๋Š” SSR์„ ์œ„ํ•ด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์˜ ๋ฐ์ดํ„ฐ ํ”„๋ฆฌํŒจ์นญ์„ ์ง€์›ํ•จ
์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ queryClient์— ์ „๋‹ฌํ•จ

๐Ÿค™ ๋ฐฉ๋ฒ• 1 : ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ํ”„๋ฆฌํŒจ์น˜ํ•˜์—ฌ initialData๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•

getStaticProps ๋‚˜ getServerSideProps ์—์„œ ์›ํ•˜๋Š” API ๋ฅผ ์š”์ฒญํ•˜๊ณ  ๊ทธ์— ๋Œ€ํ•œ ์‘๋‹ต์„ page ์— props ๋กœ ๋‚ด๋ ค์ฃผ๊ณ  ๊ทธ ๊ฐ’์„ react-query ์— initialData ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•

export async function getStaticProps() {
  const posts = await getPosts()
  return { props: { posts } }
}

function Posts(props) {
  const { data } = useQuery({
    queryKey: ['posts'],
    queryFn: getPosts,
    initialData: props.posts,
  })

  // ...
}

getStaticPropsํ•จ์ˆ˜๋กœ ์„œ๋ฒ„ ์ธก์—์„œ Post๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด. ์ด ๋ฐ์ดํ„ฐ๋Š” popsts๋ผ๋Š” ํ‚ค ๊ฐ’์œผ๋กœ props์— ์ „๋‹ฌ๋จ. ๊ทธ ๋‹ค์Œ Posts์ปดํฌ๋„ŒํŠธ์—์„œ useQuery๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ posts๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ดˆ๊ธฐ๋ฐ์ดํ„ฐ๋กœ props.posts๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •

์ฃผ์˜์ 
1. ํŠธ๋ฆฌ ๋‚ด ๋” ๊นŠ์€ ์ปดํฌ๋„ŒํŠธ์—์„œ useQuery๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ initialData๋ฅผ ๊ทธ ๊นŠ์€ ๊ณณ๊นŒ์ง€ ์ „๋‹ฌํ•ด์•ผ๋จ
2. ๋™์ผํ•œ ์ฟผ๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ์œ„์น˜์—์„œ useQuery๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ๋ชจ๋“  ์œ„์น˜์— initialData๋ฅผ ์ „๋‹ฌํ•ด์•ผ๋จ
3. ์„œ๋ฒ„์—์„œ ์ฟผ๋ฆฌ๊ฐ€ ์–ธ์ œ ๊ฐ€์ ธ์™€์กŒ๋Š”์ง€ ํŒ๋‹จ ๋ถˆ๊ฐ€๋Šฅ

๐Ÿค™ ๋ฐฉ๋ฒ• 2 : Hydration

getStaticProps or getServerSideProps์—์„œ prefetch๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์š”์ฒญ
ํ•ด๋‹น ์บ์‹œ๋ฅผ dehydrateํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ rehydrateํ•จ

์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์ „์— ๊ฐ€์ ธ์™€ ํ•ด๋‹น ์ฟผ๋ฆฌ๋“ค์„ queryClient์— ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•จ. ์ด๋Š” ์„œ๋ฒ„๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋กœ๋“œํ•  ๋•Œ ๋ฏธ๋ฆฌ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋งˆํฌ์—…์— ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•จ.
๊ทธ๋ฆฌ๊ณ  ์ด ๋ฐ์ดํ„ฐ๋Š” JS๊ฐ€ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ด์ง€๋ฉด React-query๊ฐ€ ์ด๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ฑฐ๋‚˜ Hydration ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•จ. ์ด๋Ÿฌํ•œ ๊ณผ์ •์—๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ์ดํ›„ ํ•ด๋‹น ์ฟผ๋ฆฌ๊ฐ€ ๋งŒ๋ฃŒ๋œ ๊ฒฝ์šฐ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์™€ ์ƒˆ๋กœ ๊ณ ์นจํ•˜๋Š” ๊ธฐ๋Šฅ๋„ ํฌํ•จ๋˜์–ด์žˆ์Œ.

โœ… useQuery vs Async,try/catch

๋‚œ ๋‹น์—ฐํžˆ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์ธ Hydration ๋ฐฉ๋ฒ•์„ ํƒํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฌธ๋“ ๋‹น์—ฐํ•˜๋“ฏ์ด ์“ฐ๋˜ reat-query์˜ ์บ์‹œ ๊ธฐ๋Šฅ์ด ์ •๋ง ์ž‘๋™์„ ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•ด์กŒ๋‹ค

์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€๋ดค๊ณ , ๋‘๋ฒˆ์งธ์—๋Š” useQuery๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€๋ดค๋‹ค.

๋А๋ฆฐ3G ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•˜๊ฒŒ ์‹คํ—˜ ์ง„ํ–‰

๐Ÿค™ ๋ฐฉ๋ฒ• 1 : ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹

  const getMe = async () => {
    try {
      const data = await loadMe();
      setData(data);
    } catch (err) {
      console.log(err);
    }
  };
  

์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ ํ™”๋ฉด์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋„์šฐ์ง€ ๋ชปํ•จ

๐Ÿค™ ๋ฐฉ๋ฒ• 2 : useQuery

const { data } = useQuery([QUERYKEYS.LOAD_ME], loadMe);

๋А๋ฆฐ 3Gํ™˜๊ฒฝ์ž„์—๋„ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€ ์ „ํ™˜ ๊ฐ„์— ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š์Œ.

์ž˜ ์ ์šฉ์ด ๋˜๋Š” ๋“ฏ ๐Ÿ˜Š

โœ… SSG ์ง์ ‘์‚ฌ์šฉํ•ด๋ณด๊ธฐ

SSG๋ผ๋Š”๊ฑด ๋นŒ๋“œ ์‹œ์ ์— ์„œ๋ฒ„์—์„œ ํ•ด๋‹น API๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์ด๊ธฐ๋•Œ๋ฌธ์—, ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ npm run build, npm run export๋ฅผ ํ•˜๊ณ  ์ƒ์„ฑ๋œ /out ํŒŒ์ผ์—์„œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ index.html์„ ์‹คํ–‰ํ–ˆ์„๋•Œ ํ•ด๋‹น API๋ฅผ ํ†ตํ•ด ๋ถˆ๋Ÿฌ์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜์™€์•ผํ•จ.

๋จผ์ € getStaticProps๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋ €์„๋•Œ index.html์„ ํ™•์ธํ•ด๋ณด์ž

getStaticProps๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ๊ฒฝ์šฐ index.html์„ ํ™•์ธํ•ด๋ณด์ž

export async function getStaticProps() {
  const queryClient = new QueryClient();

  await queryClient.prefetchQuery([QUERYKEYS.LOAD_PRODUCT], () =>
    loadMarketProductPaging({ size: 4, visible: true }),
  );

  return {
    props: {
      dehydratedState: dehydrate(queryClient),
    },
  };
}

๋ฐ์ดํ„ฐ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋นŒ๋“œ์‹œ์ ์— ๋„˜์–ด์˜จ ๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค!!!!!!

profile
Born to be FE developer ๐Ÿง‘๐Ÿปโ€๐Ÿ’ป

0๊ฐœ์˜ ๋Œ“๊ธ€