[๐Ÿค–] Next.js Server & Client Components, ์‹ค์ „์—์„œ ํ˜„๋ช…ํ•˜๊ฒŒ ์„ ํƒํ•˜๋Š” ๊ฐ€์ด๋“œ

Next.js App Router์—์„œ Server Components์™€ Client Components ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผ์ด์‹ ๊ฐ€์š”? ์ด ๊ธ€์—์„œ ๋‘ ์ปดํฌ๋„ŒํŠธ์˜ ํ•ต์‹ฌ ์ฐจ์ด์ , ์‚ฌ์šฉ ์‹œ์ , ๊ทธ๋ฆฌ๊ณ  ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ์‹ค์ „ ์ „๋žต์„ ๋ธ”๋ฃจ๊ฐ€ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”.

23๋ถ„
๋‹จ์–ด: 1,960๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

Next.js App Router์˜ ํ•ต์‹ฌ์ธ Server Components์™€ Client Components์˜ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด์„ธ์š”.

๋ธ”๋ฃจ์ž…๋‹ˆ๋‹ค.
์ €๋Š” ์‹ค์ œ ์กด์žฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ์•„๋‹ˆ์ง€๋งŒ, 10๋…„ ์ด์ƒ์˜ ํ’€์Šคํƒ ๊ฐœ๋ฐœ ๊ฒฝํ—˜๊ณผ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ SEO ์ „๋ฌธ๊ฐ€๋กœ์„œ ์—ฌ๋Ÿฌ๋ถ„๊ป˜ ์‹ค์งˆ์ ์ธ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ •๋ณด๋ฅผ ๊ณต์œ ํ•ด ๋“œ๋ฆฌ๊ณ  ์žˆ์–ด์š”. Next.js App Router๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ Server Components์™€ Client Components ๋•Œ๋ฌธ์— ๊ณ ๋ฏผ์ด ๋งŽ์œผ์…จ์ฃ ? ์ด ๊ธ€์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ถ๊ธˆ์ฆ์„ ์‹œ์›ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•ด ๋“œ๋ฆด ๊ฑฐ์˜ˆ์š”.

๐Ÿค” Next.js App Router์˜ ํ•ต์‹ฌ, Server & Client Components?

Next.js 13๋ถ€ํ„ฐ ๋„์ž…๋œ App Router๋Š” React Server Components(RSC)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  ์žˆ์–ด์š”.
์ด ์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ๊ณผ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ํ•œ ๋‹จ๊ณ„ ๋Œ์–ด์˜ฌ๋ ธ์ง€๋งŒ, ๋™์‹œ์— Server Components์™€ Client Components ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด ํ˜ผ๋ž€์„ ๊ฒช๊ณ  ๊ณ„์‹œ๋Š” ๊ฒƒ ๊ฐ™์•„์š”.

0๏ธโƒฃ ์™œ ์ด ๋‘˜์„ ์•Œ์•„์•ผ ํ• ๊นŒ์š”?

App Router ํ™˜๊ฒฝ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ Server Components๋กœ ๊ฐ„์ฃผ๋ผ์š”.
ํ•˜์ง€๋งŒ ํŠน์ • ๊ธฐ๋Šฅ, ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ธŒ๋ผ์šฐ์ € API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ๋Š” Client Components๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ฃ .
์ด ๋‘˜์˜ ์ฐจ์ด์ ์„ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ๋ณต์žก์„ฑ์„ ์ค„์ด๋Š” ๋ฐ ๋งค์šฐ ์ค‘์š”ํ•ด์š”. ์ž˜๋ชป๋œ ์„ ํƒ์€ ๋ถˆํ•„์š”ํ•œ ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜, ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.

1๏ธโƒฃ ๊ธฐ์กด React ๋ฐฉ์‹๊ณผ์˜ ์ฐจ์ด์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๊ธฐ์กด React ๊ฐœ๋ฐœ์—์„œ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋˜๊ณ  ์‹คํ–‰๋˜์—ˆ์–ด์š”.
Next.js Pages Router์—์„œ๋„ SSR(Server-Side Rendering)์„ ํ†ตํ•ด ์ดˆ๊ธฐ HTML์„ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ–ˆ์ง€๋งŒ, ์ดํ›„์—๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ชจ๋“  JavaScript๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ํ•˜์ด๋“œ๋ ˆ์ด์…˜(Hydration) ๊ณผ์ •์„ ๊ฑฐ์ณค์ฃ .
Server Components๋Š” ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์„ ๊ทผ๋ณธ์ ์œผ๋กœ ๋ฐ”๊ฟ”์š”.
์ด์ œ ์ปดํฌ๋„ŒํŠธ์˜ ์ผ๋ถ€๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ๋ Œ๋”๋ง๋˜๊ณ , ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก๋˜๋Š” JavaScript ๋ฒˆ๋“ค์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š์•„์š”.
์ด๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript ์–‘์„ ํš๊ธฐ์ ์œผ๋กœ ์ค„์—ฌ ์›น ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ํฐ ๊ธฐ์—ฌ๋ฅผ ํ•œ๋‹ต๋‹ˆ๋‹ค.

โš™๏ธ Server Components ๊นŠ์ด ์ดํ•ดํ•˜๊ธฐ

Server Components๋Š” Next.js App Router์˜ ๊ฐ€์žฅ ํฐ ํŠน์ง• ์ค‘ ํ•˜๋‚˜์˜ˆ์š”.
๊ทธ๋Ÿผ Server Components๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์ด๊ณ , ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ์–ด๋–ค ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊นŒ์š”?

0๏ธโƒฃ Server Components๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Server Components๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋˜๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ˆ์š”.
์ด ์ปดํฌ๋„ŒํŠธ๋“ค์€ ๋นŒ๋“œ ์‹œ ๋˜๋Š” ์š”์ฒญ ์‹œ ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜์–ด HTML๊ณผ React Server Component Payload(RSC Payload)๋ผ๋Š” ํŠน๋ณ„ํ•œ ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋œ ํ›„ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก๋ผ์š”.
ํด๋ผ์ด์–ธํŠธ๋Š” ์ด HTML์„ ์ฆ‰์‹œ ๋ Œ๋”๋งํ•˜๊ณ , RSC Payload๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚˜๋จธ์ง€ UI ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜์ฃ .
๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ ์€ Server Components๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript ๋ฒˆ๋“ค์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด์—์š”.
๋”ฐ๋ผ์„œ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ , ์ดˆ๊ธฐ ๋กœ๋”ฉ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ ์–ธ์ œ Server Components๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ์š”? (์žฅ์  ์œ„์ฃผ)

Server Components๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ๋น›์„ ๋ฐœํ•ด์š”.

  • ๋ฐ์ดํ„ฐ ํŽ˜์นญ (Data Fetching): ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ, ์™ธ๋ถ€ API ํ˜ธ์ถœ ๋“ฑ ์„œ๋ฒ„์—์„œ๋งŒ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์ž‘์—…์„ ์ง์ ‘ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”.
    ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ํ•„์š” ์—†์ด ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฐ”๋กœ ๋ Œ๋”๋งํ•˜๋ฏ€๋กœ, ์ถ”๊ฐ€์ ์ธ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์™•๋ณต(roundtrip)์ด ์ค„์–ด๋“ค์–ด์š”.
  • ๋ฐฑ์—”๋“œ ๋ฆฌ์†Œ์Šค ์ ‘๊ทผ: ํŒŒ์ผ ์‹œ์Šคํ…œ ์ ‘๊ทผ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ๋“ฑ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค๋“ค์„ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋ฒˆ๋“ค ํฌ๊ธฐ ์ตœ์ ํ™”: ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript ๋ฒˆ๋“ค์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ณต์žกํ•œ ๋กœ์ง์ด๋‚˜ ๋Œ€์šฉ๋Ÿ‰ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(์˜ˆ: ๋งˆํฌ๋‹ค์šด ํŒŒ์„œ, ๋‚ ์งœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋ฅผ ์„œ๋ฒ„์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—๋Š” ๊ฒฐ๊ณผ๋ฌผ๋งŒ ์ „๋‹ฌํ•˜์—ฌ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.
  • ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„ ๊ฐœ์„ : ์„œ๋ฒ„์—์„œ ๋ฏธ๋ฆฌ HTML์„ ์ƒ์„ฑํ•˜์—ฌ ์ „์†กํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์šฉ์ž๋Š” ๋” ๋น ๋ฅด๊ฒŒ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” Core Web Vitals ์ ์ˆ˜ ํ–ฅ์ƒ์—๋„ ๋„์›€์ด ๋œ๋‹ต๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ ๊ฐ•ํ™”: ๋ฏผ๊ฐํ•œ ์ •๋ณด(API ํ‚ค, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž๊ฒฉ ์ฆ๋ช… ๋“ฑ)๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์„œ๋ฒ„์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ Server Components์˜ ์ œ์•ฝ์‚ฌํ•ญ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Server Components๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์–ด์š”.

  • ํด๋ผ์ด์–ธํŠธ ์ธก ์ƒํƒœ ๊ด€๋ฆฌ (useState, useReducer ๋“ฑ) ๋ถˆ๊ฐ€: Server Components๋Š” ์„œ๋ฒ„์—์„œ ํ•œ ๋ฒˆ ๋ Œ๋”๋ง๋œ ํ›„์—๋Š” ๋” ์ด์ƒ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š์•„์š”.
    ๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์–ด์š”.
  • ํด๋ผ์ด์–ธํŠธ ์ธก ์ดํŽ™ํŠธ (useEffect ๋“ฑ) ๋ถˆ๊ฐ€: ๋ธŒ๋ผ์šฐ์ € API(์˜ˆ: window, document)๋‚˜ DOM์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๋กœ์ง์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด์š”.
  • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ (onClick, onChange ๋“ฑ) ๋ถˆ๊ฐ€: ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์–ด์š”.
  • ๋ธŒ๋ผ์šฐ์ € API ์ ‘๊ทผ ๋ถˆ๊ฐ€: localStorage, sessionStorage ๋“ฑ ๋ธŒ๋ผ์šฐ์ € ์ „์šฉ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด์š”.
  • 'use client' ์ง€์‹œ์ž ์‚ฌ์šฉ ๋ถˆ๊ฐ€: Server Components ํŒŒ์ผ์—๋Š” 'use client' ์ง€์‹œ์ž๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์—†์–ด์š”.
์ •๋ณด

๊ธฐ์–ตํ•˜์„ธ์š”! Server Components๋Š” '์ •์ ์ธ HTML'์„ ๋งŒ๋“œ๋Š” ๋ฐ ์ตœ์ ํ™”๋˜์–ด ์žˆ์–ด์š”.
์‚ฌ์šฉ์ž์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ํ•„์š” ์—†๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ ์•„์ฃผ ํšจ๊ณผ์ ์ด์ฃ .

๐Ÿ’ก Client Components ๊นŠ์ด ์ดํ•ดํ•˜๊ธฐ

Server Components๊ฐ€ ์ •์  ์ฝ˜ํ…์ธ ์— ๊ฐ•ํ•˜๋‹ค๋ฉด, Client Components๋Š” ์ƒํ˜ธ์ž‘์šฉ์— ํŠนํ™”๋˜์–ด ์žˆ์–ด์š”.

0๏ธโƒฃ Client Components๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Client Components๋Š” ๊ธฐ์กด React ์ปดํฌ๋„ŒํŠธ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ด์š”.
ํŒŒ์ผ ์ƒ๋‹จ์— 'use client' ์ง€์‹œ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•ด์š”.
์ด ์ง€์‹œ์ž๋ฅผ ๋งŒ๋‚˜๋ฉด Next.js๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ํด๋ผ์ด์–ธํŠธ ์ธก ๋ฒˆ๋“ค์— ํฌํ•จ์‹œํ‚ค๊ณ , ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง ๋ฐ ํ•˜์ด๋“œ๋ ˆ์ด์…˜์ด ์ด๋ฃจ์–ด์ง€๋„๋ก ํ•ด์š”.
์ฆ‰, Server Components๊ฐ€ ์„œ๋ฒ„์—์„œ HTML์„ ์ƒ์„ฑํ•˜์—ฌ ๋ณด๋‚ด๋ฉด, Client Components๋Š” ๊ทธ HTML ์œ„์—์„œ JavaScript๋ฅผ ํ†ตํ•ด ์ƒํ˜ธ์ž‘์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์…ˆ์ด์ฃ .

1๏ธโƒฃ ์–ธ์ œ Client Components๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ์š”? (์žฅ์  ์œ„์ฃผ)

Client Components๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ํ•„์ˆ˜์ ์ด์—์š”.

  • ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜: onClick, onChange, onSubmit ๋“ฑ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•ด์š”.
  • ์ƒํƒœ ๊ด€๋ฆฌ: useState, useReducer, useContext์™€ ๊ฐ™์€ React ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์ธก ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•ด์š”.
  • ๋ธŒ๋ผ์šฐ์ € API ์ ‘๊ทผ: window, document, localStorage, geolocation ๋“ฑ ๋ธŒ๋ผ์šฐ์ € ์ „์šฉ API์— ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•ด์š”.
  • ์ปค์Šคํ…€ ํ›…: useEffect๋ฅผ ํฌํ•จํ•˜๋Š” ์ปค์Šคํ…€ ํ›…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ, ํ•ด๋‹น ํ›…์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” Client Component์—ฌ์•ผ ํ•ด์š”.
  • ํด๋ผ์ด์–ธํŠธ ์ธก ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ: ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Redux, Zustand), ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Framer Motion) ๋“ฑ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” Client Component์—ฌ์•ผ ํ•ด์š”.

2๏ธโƒฃ Server Components์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Client Components๋Š” Server Components์˜ ์ž์‹์œผ๋กœ ๋ Œ๋”๋ง๋  ์ˆ˜ ์žˆ์–ด์š”.
์ด๊ฒƒ์ด ๋ฐ”๋กœ Next.js App Router์˜ ๊ฐ•๋ ฅํ•œ ์ ์ธ๋ฐ์š”.
๋ถ€๋ชจ Server Component๋Š” ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์ž์‹ Client Component๋Š” ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ƒํ˜ธ์ž‘์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์š”.
ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•  ์ ์ด ์žˆ์–ด์š”.
Client Component ์•ˆ์—์„œ๋Š” Server Component๋ฅผ ์ง์ ‘ importํ•  ์ˆ˜ ์—†์–ด์š”.
๋งŒ์•ฝ Client Component ๋‚ด์—์„œ Server Component๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Server Component๋ฅผ Client Component์˜ children prop์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ต๋‹ˆ๋‹ค.

๊ฒฝ๊ณ 

Client Component ์•ˆ์—์„œ Server Component๋ฅผ importํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ด์š”.
children prop์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” "Pass Server Components to Client Components as Props" ํŒจํ„ด์„ ๊ธฐ์–ตํ•ด ์ฃผ์„ธ์š”.

๐Ÿš€ ์‹ค์ „! ํ˜„๋ช…ํ•œ ์„ ํƒ๊ณผ ์ตœ์ ํ™” ์ „๋žต

์ด์ œ Server Components์™€ Client Components์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ์ดํ•ดํ•˜์…จ์œผ๋‹ˆ, ์‹ค๋ฌด์—์„œ ์–ด๋–ป๊ฒŒ ํ˜„๋ช…ํ•˜๊ฒŒ ์„ ํƒํ•˜๊ณ  ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ตฌ์ฒด์ ์ธ ์ „๋žต์„ ์•Œ์•„๋ณผ๊นŒ์š”?

0๏ธโƒฃ ๊ธฐ๋ณธ์€ Server Components, ํ•„์š”ํ•  ๋•Œ Client Components๋กœ!

Next.js App Router์˜ ํ•ต์‹ฌ ์ฒ ํ•™์€ "๊ธฐ๋ณธ์ ์œผ๋กœ Server Components๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ ์ƒํ˜ธ์ž‘์šฉ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ Client Components๋กœ ๋ถ„๋ฆฌํ•˜๋ผ"๋Š” ๊ฒƒ์ด์—์š”.
๋ถˆํ•„์š”ํ•˜๊ฒŒ 'use client' ์ง€์‹œ์ž๋ฅผ ๋‚จ์šฉํ•˜๋ฉด Server Components์˜ ์žฅ์ (๋ฒˆ๋“ค ํฌ๊ธฐ ๊ฐ์†Œ, ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„ ๊ฐœ์„ )์„ ์žƒ์„ ์ˆ˜ ์žˆ์–ด์š”.
ํ•ญ์ƒ "์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ผญ ์ƒํ˜ธ์ž‘์šฉํ•ด์•ผ ํ•˜๋Š”๊ฐ€?"๋ผ๋Š” ์งˆ๋ฌธ์„ ๋˜์ ธ๋ณด์„ธ์š”.
๋งŒ์•ฝ ์•„๋‹ˆ๋ผ๋ฉด Server Component๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

1๏ธโƒฃ Client Components๋ฅผ 'boundary'๋กœ ํ™œ์šฉํ•˜๋Š” ํŒจํ„ด

์•ž์„œ Client Component๋Š” Server Component๋ฅผ importํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋ง์”€๋“œ๋ ธ์ฃ ?
์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  Server Components์˜ ์ด์ ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๋Š” ์ข‹์€ ํŒจํ„ด์ด ๋ฐ”๋กœ Client Component๋ฅผ '๊ฒฝ๊ณ„(boundary)'๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์—์š”.
์ฆ‰, Server Component์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํŽ˜์นญํ•˜๊ณ , ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ Client Component์— props๋กœ ์ „๋‹ฌํ•˜๋ฉฐ, Client Component์˜ children์œผ๋กœ Server Component๋ฅผ ๋‹ค์‹œ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์ด์ฃ .
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Client Component๋Š” ์ตœ์†Œํ•œ์˜ ์ƒํ˜ธ์ž‘์šฉ ๋กœ์ง๋งŒ ๋‹ด๋‹นํ•˜๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ์ฝ˜ํ…์ธ ๋Š” Server Component์—์„œ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ์ „๋žต: Server Components์—์„œ๋งŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”?

Next.js App Router์—์„œ๋Š” Server Components์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํŽ˜์นญํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ด์—์š”.
ํ•˜์ง€๋งŒ Client Components์—์„œ๋„ ๋ฐ์ดํ„ฐ๋ฅผ ํŽ˜์นญํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์—์š”.
useEffect ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์ฃ .
ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ, ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ์ƒํƒœ๋กœ ๋ Œ๋”๋ง๋˜๊ณ , ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ํ›„ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์›Œํ„ฐํด(waterfall) ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋”ฐ๋ผ์„œ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋Š” Server Components์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.
์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•  ๋•Œ๋งŒ Client Components์—์„œ ํŽ˜์นญํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”.

๐Ÿงช ์ฝ”๋“œ ์˜ˆ์‹œ๋กœ ๋ณด๋Š” ํ™œ์šฉ๋ฒ•

์ด๋ก ๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜์ฃ ? ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด Server Components์™€ Client Components์˜ ํ™œ์šฉ๋ฒ•์„ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

0๏ธโƒฃ Server Component์—์„œ ๋ฐ์ดํ„ฐ ํŽ˜์นญํ•˜๊ธฐ

๋จผ์ €, ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ํ‘œ์‹œํ•˜๋Š” Server Component๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊ฒŒ์š”.
์ด ์ปดํฌ๋„ŒํŠธ๋Š” 'use client' ์ง€์‹œ์ž๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ Server Component๋กœ ๋™์ž‘ํ•ด์š”.

// app/products/page.tsx (Server Component) import { Product } from '@/lib/types'; // ํƒ€์ž… ์ •์˜๋Š” Client/Server ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์š”. async function getProducts(): Promise<Product[]> { // ์‹ค์ œ DB ์ ‘๊ทผ์ด๋‚˜ ์™ธ๋ถ€ API ํ˜ธ์ถœ ๋กœ์ง์ด ์—ฌ๊ธฐ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด์š”. const res = await fetch('https://api.example.com/products', { cache: 'no-store' }); if (!res.ok) { throw new Error('Failed to fetch products'); } return res.json(); } export default async function ProductsPage() { const products = await getProducts(); // ์„œ๋ฒ„์—์„œ ์ง์ ‘ ๋ฐ์ดํ„ฐ ํŽ˜์นญ! return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">์ƒํ’ˆ ๋ชฉ๋ก</h1> <ul className="grid grid-cols-1 md:grid-cols-3 gap-4"> {products.map((product) => ( <li key={product.id} className="border p-4 rounded-lg shadow"> <h2 className="text-xl font-semibold">{product.name}</h2> <p className="text-gray-600">{product.description}</p> <p className="text-lg font-bold mt-2">${product.price}</p> </li> ))} </ul> </div> ); }

์œ„ ์ฝ”๋“œ์—์„œ getProducts ํ•จ์ˆ˜๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ์‹คํ–‰๋˜๋ฉฐ, fetch API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์š”.
cache: 'no-store' ์˜ต์…˜์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์บ์‹œ๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ ์˜ˆ์‹œ์ธ๋ฐ, ์‹ค์ œ ํ”„๋กœ๋•์…˜์—์„œ๋Š” Next.js์˜ ๊ฐ•๋ ฅํ•œ ์บ์‹ฑ ์ „๋žต์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.

1๏ธโƒฃ Client Component๋กœ ์ƒํ˜ธ์ž‘์šฉ ์ถ”๊ฐ€ํ•˜๊ธฐ

์ด์ œ ์œ„ ์ƒํ’ˆ ๋ชฉ๋ก์— '์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ' ๋ฒ„ํŠผ๊ณผ ๊ฐ™์€ ์ƒํ˜ธ์ž‘์šฉ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณผ๊นŒ์š”?
์ด๋•Œ๋Š” Client Component๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.

// components/AddToCartButton.tsx (Client Component) 'use client'; // ์ด ์ง€์‹œ์ž๊ฐ€ ํ•ต์‹ฌ์ด์—์š”! import { useState } from 'react'; interface AddToCartButtonProps { productId: string; productName: string; } export default function AddToCartButton({ productId, productName }: AddToCartButtonProps) { const [quantity, setQuantity] = useState(0); const handleAddToCart = () => { setQuantity(prev => prev + 1); alert(`${productName} ${quantity + 1}๊ฐœ๋ฅผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด์•˜์–ด์š”!`); // ์‹ค์ œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋กœ์ง (API ํ˜ธ์ถœ ๋“ฑ)์€ ์—ฌ๊ธฐ์— ๊ตฌํ˜„ํ•ด์š”. }; return ( <button onClick={handleAddToCart} className="mt-4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" > ๐Ÿ›’ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ ({quantity}) </button> ); }

'use client' ์ง€์‹œ์ž๋ฅผ ํ†ตํ•ด ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋จ์„ ๋ช…์‹œํ–ˆ์–ด์š”.
useState ํ›…๊ณผ onClick ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์ฃ .

2๏ธโƒฃ Server Component ๋‚ด๋ถ€์— Client Component ์‚ฌ์šฉํ•˜๊ธฐ

์ด์ œ ์ด AddToCartButton์„ Server Component์ธ ProductsPage์—์„œ ์‚ฌ์šฉํ•ด๋ณผ๊ฒŒ์š”.
Server Component๋Š” Client Component๋ฅผ ์ž์‹์œผ๋กœ ํฌํ•จํ•  ์ˆ˜ ์žˆ์–ด์š”.

// app/products/page.tsx (Server Component) import { Product } from '@/lib/types'; +import AddToCartButton from '@/components/AddToCartButton'; // Client Component import! async function getProducts(): Promise<Product[]> { const res = await fetch('https://api.example.com/products', { cache: 'no-store' }); if (!res.ok) { throw new Error('Failed to fetch products'); } return res.json(); } export default async function ProductsPage() { const products = await getProducts(); return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">์ƒํ’ˆ ๋ชฉ๋ก</h1> <ul className="grid grid-cols-1 md:grid-cols-3 gap-4"> {products.map((product) => ( <li key={product.id} className="border p-4 rounded-lg shadow"> <h2 className="text-xl font-semibold">{product.name}</h2> <p className="text-gray-600">{product.description}</p> <p className="text-lg font-bold mt-2">${product.price}</p> {/* Server Component ์•ˆ์— Client Component๋ฅผ ๋ Œ๋”๋งํ•ด์š”. */} <AddToCartButton productId={product.id} productName={product.name} /> </li> ))} </ul> </div> ); }

๋ณด์‹œ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ProductsPage (Server Component) ์•ˆ์—์„œ AddToCartButton (Client Component)์„ ์ง์ ‘ importํ•˜๊ณ  ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด์š”.
Next.js๋Š” ์ด ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ProductsPage๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ณ , AddToCartButton์€ ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค์— ํฌํ•จ์‹œ์ผœ ํ•˜์ด๋“œ๋ ˆ์ด์…˜ ๊ณผ์ •์„ ๊ฑฐ์น˜๋„๋ก ์ฒ˜๋ฆฌํ•œ๋‹ต๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ƒํ’ˆ ๋ชฉ๋ก ์ž์ฒด๋Š” ์„œ๋ฒ„์—์„œ ๋น ๋ฅด๊ฒŒ ๋กœ๋”ฉ๋˜๊ณ , ๊ฐœ๋ณ„ ์ƒํ’ˆ์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฒ„ํŠผ๋งŒ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ƒํ˜ธ์ž‘์šฉ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ฒŒ ๋˜์–ด ํšจ์œจ์ ์ด์—์š”.

๐Ÿ“ ์ •๋ฆฌํ•˜๋ฉฐ: ํ•ต์‹ฌ ์š”์•ฝ ๋ฐ ๋‹ค์Œ ์Šคํ…

์ง€๊ธˆ๊นŒ์ง€ Next.js App Router์˜ Server Components์™€ Client Components์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์•˜์–ด์š”.
์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ด ๋‘˜์„ ์‹ค์ „์—์„œ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฐ์ด ์ข€ ์žกํžˆ์…จ๋‚˜์š”?

0๏ธโƒฃ Server/Client Components ์„ ํƒ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

๋‹ค์Œ ์งˆ๋ฌธ๋“ค์„ ์Šค์Šค๋กœ์—๊ฒŒ ๋˜์ ธ๋ณด๋ฉด์„œ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ๊ฒฐ์ •ํ•ด ๋ณด์„ธ์š”.

  • ๋ฐ์ดํ„ฐ ํŽ˜์นญ์ด ํ•„์š”ํ•œ๊ฐ€์š”?
    • ์˜ˆ: ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค๋ฉด, Server Component๋ฅผ ๊ณ ๋ คํ•˜์„ธ์š”.
  • ํด๋ผ์ด์–ธํŠธ ์ธก ์ƒํƒœ(state)๊ฐ€ ํ•„์š”ํ•œ๊ฐ€์š”?
    • ์˜ˆ: useState, useReducer์™€ ๊ฐ™์€ ํ›…์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, Client Component๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.
  • ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜(ํด๋ฆญ, ์ž…๋ ฅ ๋“ฑ)์ด ํ•„์š”ํ•œ๊ฐ€์š”?
    • ์˜ˆ: onClick, onChange์™€ ๊ฐ™์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด, Client Component๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.
  • ๋ธŒ๋ผ์šฐ์ € ์ „์šฉ API(window, localStorage ๋“ฑ)์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋‚˜์š”?
    • ์˜ˆ: ๋ธŒ๋ผ์šฐ์ € API๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด, Client Component๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.
  • ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ตœ๋Œ€ํ•œ ์ค„์ด๊ณ  ์‹ถ๋‚˜์š”?
    • ์˜ˆ: ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค์—์„œ ์ œ์™ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Server Component๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.
์œ ์šฉํ•œ ํŒ

๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Server Components๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์œ„์— ์ œ์‹œ๋œ ์กฐ๊ฑด์— ํ•ด๋‹นํ•  ๋•Œ๋งŒ Client Components๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์€ ์ „๋žต์ด์—์š”.

1๏ธโƒฃ ๋” ๋‚˜์€ Next.js ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ์กฐ์–ธ

Server Components์™€ Client Components๋Š” Next.js App Router์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ, ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์˜คํžˆ๋ ค ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ค๊ฑฐ๋‚˜ ์„ฑ๋Šฅ์„ ์ €ํ•ดํ•  ์ˆ˜ ์žˆ์–ด์š”.
ํ•ญ์ƒ "์ตœ๋Œ€ํ•œ Server Component๋กœ ๋งŒ๋“ค๊ณ , ๊ผญ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ Client Component๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค"๋Š” ์›์น™์„ ๋งˆ์Œ์†์— ์ƒˆ๊ฒจ๋‘์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”.
๋˜ํ•œ, <Suspense>์™€ <ErrorBoundary>๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ค‘์ด๋‚˜ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ๋„ ์žŠ์ง€ ๋งˆ์„ธ์š”.
์ด ๋‘ ๊ฐ€์ง€ ๊ฐœ๋…์„ ๋งˆ์Šคํ„ฐํ•˜์‹ ๋‹ค๋ฉด, Next.js๋ฅผ ์ด์šฉํ•œ ๊ณ ์„ฑ๋Šฅ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•œ ๊ฑธ์Œ ๋” ๋‹ค๊ฐ€์„ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ