Frontend ๐Ÿ“š/React

[React] ์‚ฌ์ „ ๋ Œ๋”๋ง, Suspense etc.

leejaejae 2024. 7. 24. 13:50

โ˜… ์ด์ „ ํฌ์ŠคํŒ…๊ณผ ์ด์–ด์ง‘๋‹ˆ๋‹ค!

2024.07.12 - [Frontend ๐Ÿ“š/React] - [React] ํ•˜์ด๋“œ๋ ˆ์ด์…˜(Hydration), Next etc.

 

[React] ๋ฆฌ์•กํŠธ ๊ธฐ์ˆ  ๋ฉด์ ‘ ํ•ธ๋“œ๋ถ VII - ํ•˜์ด๋“œ๋ ˆ์ด์…˜(Hydration), Next etc.

1. ํ•˜์ด๋“œ๋ ˆ์ด์…˜2. Next.JS1. ํ•˜์ด๋“œ๋ ˆ์ด์…˜(Hydration) โญ๏ธํ•˜์ด๋“œ๋ ˆ์ด์…˜๋ฆฌ์•กํŠธ์—์„œ ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ํ˜น์€ SSG(์Šคํƒœํ‹ฑ ์‚ฌ์ดํŠธ ์ œ๋„ค๋ ˆ์ด์…˜)์„ ์‹คํ–‰ํ•œ HTML ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„์˜จ ๋’ค, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด๊ฒƒ์„ ๋‹ค

jaejae-sosp.tistory.com

 

1. ์‚ฌ์ „ ๋ Œ๋”๋ง ํ•จ์ˆ˜ ์ข…๋ฅ˜ โญ๏ธ

  • getInitialProps
    • Next 9.3 ๋ฒ„์ „ ์ด์ „์—๋Š” getInitialProps๋งŒ์œผ๋กœ ์‚ฌ์ „ ๋ Œ๋”๋ง ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ์ „๋ถ€ ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ, 9.3 ๋ฒ„์ „๋ถ€ํ„ฐ๋Š” getInitialProps๊ฐ€ 3๊ฐ€์ง€๋กœ ๋ถ„๋ฆฌ๋จ
    • getStaticProps, getStaticPath, getServerSideProps
  • getStaticProps
    • ๋นŒ๋“œ์‹œ ๊ณ ์ •๋˜๋Š” ๊ฐ’์œผ๋กœ ๋นŒ๋“œ ์ดํ›„์—๋Š” ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•จ
    • data๋ฅผ ๋นŒ๋“œ ์‹œ์— ๋ฏธ๋ฆฌ ๋•ก๊ฒจ์™€ ์ •์ (static)์œผ๋กœ ์ œ๊ณต
    • ๋งค ์œ ์ €์˜ ์š”์ฒญ๋งˆ๋‹ค fetchํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์œ ๋ฆฌํ•จ
    • ์œ ์ €์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  ํผ๋ธ”๋ฆญํ•˜๊ฒŒ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ž„
    • SEO ๋“ฑ์˜ ์ด์Šˆ๋กœ ์ธํ•ด ๋น ๋ฅด๊ฒŒ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•ด์•ผ๋งŒ ํ•˜๋Š” ํŽ˜์ด์ง€์— ์‚ฌ์šฉ
  • getStaticPath
    • ๋™์  ๋ผ์šฐํŒ… + getStaticProps๋ฅผ ์›ํ•  ๋•Œ ์‚ฌ์šฉ
    • ์ •์˜ํ•˜์ง€ ์•Š์€ ํ•˜์œ„ ๊ฒฝ๋กœ๋Š” ์ ‘๊ทผํ•ด๋„ ํ™”๋ฉด์ด ๋œจ์ง€ ์•Š์Œ(error ํŽ˜์ด์ง€๋กœ ๋ผ์šฐํŒ…)
    • ๋™์  ๋ผ์šฐํŒ… ์‹œ, ๋ผ์šฐํŒ…๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ๋„ฃ์–ด์•ผ ํ•จ
  • getServerSideProps
    • ๋นŒ๋“œ์™€ ์ƒ๊ด€์—†์ด, ๋งค ํŽ˜์ด์ง€ ์š”์ฒญ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜ด

 

2. Suspense โญ๏ธ

  • Suspense๋ž€?
    • Suspense๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹˜

    • Suspense๋Š” '์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฝ์–ด๋“ค์ด๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์•˜๋‹ค'๊ณ  React์— ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋Š”, ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ž„
    • ์ดํ›„์— React๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ UI๋ฅผ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Œ

    • ์žฅ๊ธฐ์ ์ธ ๊ด€์ ์œผ๋กœ๋Š”, Suspense๊ฐ€ ๋ฐ์ดํ„ฐ ์ถœ์ฒ˜์™€ ์ƒ๊ด€์—†์ด ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๋ฐ์— ์‚ฌ์šฉ๋˜๋Š” ์ฃผ๋œ ๋ฐฉ์‹์œผ๋กœ  ์‚ฌ์šฉ๋˜๊ธธ ๋ฐ”๋žŒ
const resource = fetchProfileData();

function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // ์•„์ง ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋”๋ผ๋„, ์‚ฌ์šฉ์ž ์ •๋ณด ์ฝ๊ธฐ๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // ์•„์ง ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋”๋ผ๋„, ๊ฒŒ์‹œ๊ธ€ ์ฝ๊ธฐ๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค
  const posts = resource.posts.read();
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
  • Suspense๋กœ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€?
    • ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค(axios, SWR, react-query)์ด React์™€ ๊นŠ๊ฒŒ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ
    • ์˜๋„์ ์œผ๋กœ ์„ค๊ณ„๋œ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ. suspense๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์ ธ์•ผ ํ•˜๋Š”์ง€๋ฅผ ์ •ํ•˜์ง€ ์•Š๊ณ , ์•ฑ์˜ ์‹œ๊ฐ์ ์ธ ๋กœ๋”ฉ ๋‹จ๊ณ„๋ฅผ ๋ฐ€์ ‘ํ•˜๊ฒŒ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ.
    • ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์›€. await๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋Š” ์ข…์ข… ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์›€, suspense๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์ง€๊ฒŒ ํ•ด์คŒ.