Step 1 Tech Stack Selection - 100-hours-a-week/16-team-katopia-fe GitHub Wiki

๐Ÿ“‹ FITCHECK ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ์ˆ  ์Šคํƒ ์„ ์ • ๋ฌธ์„œ


ํ”„๋กœ์ ํŠธ ์„ฑ๊ฒฉ๊ณผ ๊ธฐ์ˆ  ์Šคํƒ ์„ ์ • ๊ธฐ์ค€

๋ณธ ํ”„๋กœ์ ํŠธ FITCHECK๋Š” ์ด๋ฏธ์ง€ ์ค‘์‹ฌ์˜ ํŒจ์…˜ SNS๋กœ ์ธํ„ฐ๋ž™์…˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.

๊ธฐ์ˆ  ์Šคํƒ์€ ๋‹จ์ˆœํ•œ ๊ตฌํ˜„ ํŽธ์˜์„ฑ์ด ์•„๋‹Œ, ์‹ค์ œ ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ์˜ ์„ฑ๋Šฅ, ํ™•์žฅ์„ฑ, ์šด์˜ ์•ˆ์ •์„ฑ์„ ์ตœ์šฐ์„  ๊ธฐ์ค€์œผ๋กœ ์„ ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ณ ๋ ค ์‚ฌํ•ญ

  • ๊ณ ์šฉ๋Ÿ‰ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ
    • ํ”ผ๋“œ ๋ฐ ํ”„๋กœํ•„์—์„œ ์ด๋ฏธ์ง€ ๋…ธ์ถœ ๋น„์ค‘์ด ๋งค์šฐ ๋†’์Œ
  • ์žฆ์€ ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜
    • ์ข‹์•„์š”, ๋Œ“๊ธ€, ๋ถ๋งˆํฌ, ํˆฌํ‘œ ๋“ฑ ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ๋ฆฌ๋ Œ๋”๋ง ๋นˆ๋„ ๋†’์Œ
  • ๊ถŒํ•œ๋ณ„ UX ์ฐจ๋“ฑ
    • ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ฝ˜ํ…์ธ  ์ผ๋ถ€ ๊ณต๊ฐœ
    • ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ๋กœ๊ทธ์ธ ์„ธ์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์ œ๊ณต

๋”ฐ๋ผ์„œ ๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ๊ณผ ์ธํ„ฐ๋ž™์…˜ ์•ˆ์ •์„ฑ์„ ํ•ต์‹ฌ ํŒ๋‹จ ๊ธฐ์ค€์œผ๋กœ ์‚ผ์•˜์Šต๋‹ˆ๋‹ค.


๐Ÿ“Š ์„ฑ๋Šฅ ์ •์˜ ๋ฐ ์ธก์ • ๊ธฐ์ค€ (Web Vitals)

์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ & ์ธํ„ฐ๋ž™์…˜ ์•ˆ์ •์„ฑ ์ •์˜

์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ๊ณผ ์ธํ„ฐ๋ž™์…˜ ์•ˆ์ •์„ฑ์€ ๋‹จ์ˆœํ•œ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์‹œ๊ฐ„๋งŒ์œผ๋กœ ํŒ๋‹จํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ๋น„์ค‘์ด ๋†’๊ณ  ์ƒํƒœ ๋ณ€๊ฒฝ์ด ์žฆ์€ ์„œ๋น„์Šค์—์„œ๋Š” โ€œ์–ธ์ œ ๋ณด์ด๊ธฐ ์‹œ์ž‘ํ–ˆ๋Š”์ง€โ€์™€ โ€œ์–ผ๋งˆ๋‚˜ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์‘ํ•˜๋Š”์ง€โ€๊ฐ€ ํ•ต์‹ฌ ๊ธฐ์ค€์ด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฒด๊ฐ ์š”์†Œ๋Š” Web Vitals ์ง€ํ‘œ๋ฅผ ํ†ตํ•ด ์ •๋Ÿ‰์ ์œผ๋กœ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ (Perceived Performance)

์ง€ํ‘œ ์ •์˜ ์˜ˆ์‹œ ๊ทผ๊ฑฐ
LCP (Largest Contentful Paint) ํ™”๋ฉด์—์„œ ๊ฐ€์žฅ ํฐ ์ฝ˜ํ…์ธ ๊ฐ€ ์™„์ „ํžˆ ๋ Œ๋”๋ง ๋˜๋Š” ์‹œ์  ํ™ˆ ํ”ผ๋“œ ์ง„์ž… ํ›„ ๋ฉ”์ธ ์ด๋ฏธ์ง€๊ฐ€ ์™„์ „ํžˆ ๋กœ๋”ฉ๋˜์–ด ์„ ๋ช…ํ•˜๊ฒŒ ๋ณด์ด๋Š” ์ˆœ๊ฐ„ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์งˆ์ ์œผ๋กœ ๋А๋ผ๋Š” ๋กœ๋”ฉ ์†๋„
- next/image๋ฅผ ํ†ตํ•œ ์ž๋™ ๋ฆฌ์‚ฌ์ด์ง• ๋ฐ WebP ๋ณ€ํ™˜
- ์ผ๋ฐ˜ <img> ๋Œ€๋น„ LCP ๋‹จ์ถ•
FCP (First Contentful Paint) ํ™”๋ฉด์—์„œ ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ Œ๋”๋ง ๋˜๋Š” ์‹œ์  ํŽ˜์ด์ง€ ์ ‘์† ํ›„ ํฐ ํ™”๋ฉด์—์„œ ๋กœ๊ณ ยทํ…์ŠคํŠธยท์Šค์ผˆ๋ ˆํ†ค ๋“ฑ ์ฒซ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ์ˆœ๊ฐ„ ์‚ฌ์šฉ์ž๊ฐ€ "๋กœ๋”ฉ์ด ์‹œ์ž‘๋˜์—ˆ๋‹ค"๋Š” ์‹œ๊ฐ์  ์‹ ํ˜ธ๋ฅผ ์ฃผ๋Š” ์ง€ํ‘œ
- Next.js์˜ Server-Side Rendering์„ ํ†ตํ•ด ๋นˆ ํ™”๋ฉด ๋…ธ์ถœ ์ตœ์†Œํ™”
CLS (Cumulative Layout Shift) ํ™”๋ฉด์ด ์–ผ๋งˆ๋‚˜ ๋ถˆ์•ˆ์ •ํ•œ์ง€๋ฅผ ์ธก์ •ํ•˜๋Š” ์ง€ํ‘œ ๊ฒŒ์‹œ๋ฌผ์„ ๋ณด๋‹ค๊ฐ€ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ์œผ๋กœ ์ข‹์•„์š” ๋ฒ„ํŠผ ์œ„์น˜๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋ฐ€๋ฆฌ๋Š” ํ˜„์ƒ ํ™”๋ฉด์—์„œ ๋ ˆ์ด์•„์›ƒ์ด ๋ฐ€๋ฆฌ๋Š” ์ •๋„
- ์ด๋ฏธ์ง€ ๋น„์œจ ์‚ฌ์ „ ํ™•๋ณด- Placeholder ์ ์šฉ์„ ํ†ตํ•œ ๋ ˆ์ด์•„์›ƒ ์•ˆ์ •์„ฑ ํ™•๋ณด
TTI (Time to Interactive) ํด๋ฆญ์ด๋‚˜ ์ž…๋ ฅ ๊ฐ™์€ ์œ ์ €์˜ ์ธํ„ฐ๋ž™์…˜์ด ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋˜๋Š” ์‹œ์  ํ™”๋ฉด์€ ์ด๋ฏธ ๋ณด์ด์ง€๋งŒ, ์ข‹์•„์š” ๋ฒ„ํŠผ์ด ์‹ค์ œ๋กœ ํด๋ฆญ ๊ฐ€๋Šฅํ•ด์ง€๋Š” ์‹œ์  - ์ธํ„ฐ๋ž™์…˜ ์š”์†Œ ์šฐ์„  ํ•˜์ด๋“œ๋ ˆ์ด์…˜

์ธํ„ฐ๋ž™์…˜ ์•ˆ์ •์„ฑ (Interaction Stability)

INP (Interaction to Next Paint)

์‚ฌ์šฉ์ž๊ฐ€ ์ธํ„ฐ๋ž™์…˜์„ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ ๊ฒฐ๊ณผ๋กœ ๋‹ค์Œ UI๋ฅผ ๊ทธ๋ ค๋‚ด๋Š”๋ฐ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„

  • TanStack Query v5์˜ ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ ์ ์šฉ -> ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ๋ž€? ์‚ฌ์šฉ์ž์˜ ๋™์ž‘ ๊ฒฐ๊ณผ๋ฅผ ์„œ๋ฒ„์—์„œ ์„ฑ๊ณต์„ ํ–ˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ์ฆ‰์‹œ UI๋ฅผ ๋ฐ˜์˜ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ. ๋งŒ์•ฝ, ์„œ๋ฒ„์—์„œ ์‹คํŒจ์‹œ ์›๋ž˜ UI๋กœ ๋Œ๋ ค๋ฒ„๋ฆผ.
  • ์„œ๋ฒ„ ์‘๋‹ต ์ด์ „์— UI ์ฆ‰์‹œ ๋ฐ˜์˜ํ•˜์—ฌ INP ์ตœ์†Œํ™”

์„ฑ๋Šฅ ์ธก์ • ๋ฐ ๊ฒ€์ฆ ๋„๊ตฌ

  • Lighthouse
    • Web Vitals ๊ธฐ๋ฐ˜ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์„ฑ๋Šฅ ์ ์ˆ˜ ๋น„๊ต
  • React Profiler
    • Zustand ์ ์šฉ ํ›„ ๋ Œ๋”๋ง ๋ฒ”์œ„ ๋ฐ ์„ฑ๋Šฅ ์‹œ๊ฐ์  ๊ฒ€์ฆ

ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ์ˆ  ์Šคํƒ

๋ถ„๋ฅ˜ ๊ธฐ์ˆ  ๋ฒ„์ „
Framework Next.js (App Router) ^16.x
Language TypeScript ^5.x
Server State TanStack Query ^5.x
Client State Zustand ^4.x
Form React Hook Form ^7.x
Validation Zod ^3.x
Styling Tailwind CSS ^3.x

1๏ธโƒฃ Framework โ€” Next.js (App Router)

์™œ Next.js์ธ๊ฐ€

FITCHECK๋Š” ๋‹จ์ˆœ SPA๊ฐ€ ์•„๋‹ˆ๋ผ ์™ธ๋ถ€ ์œ ์ž… โ†’ ์ฝ˜ํ…์ธ  ์†Œ๋น„ โ†’ ์ธํ„ฐ๋ž™์…˜ ์ „ํ™˜ ํ๋ฆ„์ด ์ค‘์š”ํ•œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

Next.js๋Š” ๋‹ค์Œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ตฌ์กฐ์ ์œผ๋กœ ๋งŒ์กฑํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ๋ Œ๋”๋ง ๊ธฐ๋ฐ˜ ์ดˆ๊ธฐ ํ™”๋ฉด ์ œ๊ณต
  • ์ฝ˜ํ…์ธ  ๋‹จ์œ„ ํŽ˜์ด์ง€์˜ ์˜๋ฏธ ์žˆ๋Š” HTML ์ œ๊ณต
  • SEO ๋ฐ ๊ณต์œ (OG) ๋Œ€์‘
  • ์ด๋ฏธ์ง€ ์ค‘์‹ฌ ์„œ๋น„์Šค์— ์ตœ์ ํ™”๋œ ๊ธฐ๋ณธ ์„ฑ๋Šฅ ๊ตฌ์กฐ

App Router์™€ use client ์„ค๊ณ„ ์˜๋„

Next.js App Router์˜ ๊ธฐ๋ณธ ์ „์ œ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” Server Component๋กœ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ด๋Š” "ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ JS๋ฅผ ๋‚ด๋ ค๋ณด๋‚ธ๋‹ค."๋Š” ๋ช…ํ™•ํ•œ ๋ฐฉํ–ฅ์„ฑ์„ ๊ฐ€์ง€๋ฉฐ, ๋ณธ ํ”„๋กœ์ ํŠธ์˜ ํ™”๋ฉด ๊ตฌ์„ฑ ๋ฐฉ์‹๊ณผ ์ž˜ ๋งž์Šต๋‹ˆ๋‹ค.

Server Component์˜ ์žฅ์ 

  • ํด๋ผ์ด์–ธํŠธ JS ๋ฒˆ๋“ค ํฌ๊ธฐ ๊ฐ์†Œ
  • ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„ ๊ฐœ์„ 
  • ๋ฏผ๊ฐํ•œ ๋กœ์ง์„ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœํ•˜์ง€ ์•Š์Œ

์ด ๊ตฌ์กฐ์—์„œ use client๋Š” โ€œ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์™œ ํด๋ผ์ด์–ธํŠธ์—ฌ์•ผ ํ•˜๋Š”์ง€โ€๋ฅผ ๋ช…์‹œํ•˜๋Š” ์„ ์–ธ์ž…๋‹ˆ๋‹ค.


React + Vite์™€ Next.js

FITCHECK๋Š” ๋‹จ์ˆœ SPA๊ฐ€ ์•„๋‹ˆ๋ผ ์ฝ˜ํ…์ธ  ๋…ธ์ถœ ๊ตฌ์กฐ์™€ ์•ฑํ˜• ์ธํ„ฐ๋ž™์…˜์ด ๊ณต์กดํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ๋ฐฉ์‹๊ณผ ํ”„๋ ˆ์ž„์›Œํฌ ์„ ํƒ์— ๋”ฐ๋ผ ์„ฑ๋Šฅ, ํ™•์žฅ์„ฑ, ๋งˆ์ผ€ํŒ… ํšจ์œจ์ด ํฌ๊ฒŒ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์–ด Next.js์™€ React + Vite๋ฅผ ์ฃผ์š” ํ›„๋ณด๋กœ ๋น„๊ตํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ญ๋ชฉ Next.js (์ฝ˜ํ…์ธ ยทํ™•์žฅ์„ฑ ์ค‘์‹ฌ) React + Vite (๊ฐœ๋ฐœ ํšจ์œจ ์ค‘์‹ฌ)
๊ธฐ๋ณธ ๋ Œ๋”๋ง Server-first Client-only
๋น„๋กœ๊ทธ์ธ ํ”ผ๋“œ SEO ๊ธฐ๋ฐ˜ ์œ ์ž… ๊ฐ€๋Šฅ ์ฒดํ—˜์šฉ ํ™”๋ฉด์— ํ•œ์ •
OG/๊ณต์œ  ์ž๋™ HTML/๋ฉ”ํƒ€ ์ƒ์„ฑ ๋ณ„๋„ ์„œ๋ฒ„ ์ž‘์—… ํ•„์š”
๋ฐ์ดํ„ฐ ๋ณด์•ˆ Server Component๋กœ ๋กœ์ง ์€๋‹‰ ๋กœ์ง ์ „๋ถ€ ํด๋ผ์ด์–ธํŠธ ๋…ธ์ถœ
์žฅ๊ธฐ ํ™•์žฅ ์ฝ˜ํ…์ธ ยท๋งˆ์ผ€ํŒ… ์นœํ™”์  ๋‚ด๋ถ€ UX ์ค‘์‹ฌ

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ๋กœ๊ทธ์ธ ์ด์ „์—๋„ ์ฝ˜ํ…์ธ ๊ฐ€ ๋…ธ์ถœ๋˜๊ณ  ์ด๋ฅผ ํ†ตํ•ด ์œ ์ž…๊ณผ ์ „ํ™˜์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ตฌ์กฐ์˜ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์„ฑ์ƒ ์ดˆ๊ธฐ HTML ๊ธฐ๋ฐ˜ ์ฝ˜ํ…์ธ  ์ œ๊ณต, SEO ๋Œ€์‘, ๊ณต์œ  ์ตœ์ ํ™”๊ฐ€ ํ•„์ˆ˜์ ์ด๋ฉฐ, ๋ชจ๋“  ๋ Œ๋”๋ง์„ ํด๋ผ์ด์–ธํŠธ์— ์˜์กดํ•˜๋Š” React+Vite ๊ตฌ์กฐ๋Š” ์žฅ๊ธฐ์ ์œผ๋กœ ํ•œ๊ณ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. Next.js๋Š” ์ด๋Ÿฌํ•œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ถฉ์กฑํ•˜๋ฉฐ ์ฝ˜ํ…์ธ  ์ค‘์‹ฌ ์„œ๋น„์Šค๋กœ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

React+Vite๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ƒํƒœ๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ์—†๋Š” ์ •์  UI ๊นŒ์ง€๋„ ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค์— ํฌํ•จ๋˜๋ฉฐ ์„œ๋น„์Šค ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ฒˆ๋“ค ํฌ๊ธฐ ์ฆ๊ฐ€์™€ ์„ฑ๋Šฅ ๊ด€๋ฆฌ ๋ถ€๋‹ด์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Nest.js(App Router)๋Š” Server Component๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ๋กœ์ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ use client๋ฅผ ๋ช…์‹œํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ๋Š” ๋ถˆํ•„์š”ํ•œ ํด๋ผ์ด์–ธํŠธ ๋กœ์ง ํ™•์žฅ์„ ์‚ฌ์ „์— ์–ต์ œํ•˜๊ณ  ๋ Œ๋”๋ง ์ฑ…์ž„์„ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ ์ค‘์‹ฌ ํ™”๋ฉด๊ณผ ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜ UI๊ฐ€ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„๋˜๋Š” ์„œ๋น„์Šค์ด๋ฏ€๋กœ, ์ •์  UI๋Š” Server Component, ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์€ Client Component๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์„ฑ๋Šฅ ์•ˆ์ •์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ํ•ฉ๋ฆฌ์ ์ธ ๊ตฌ์กฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.


์ด๋ฏธ์ง€ ์ค‘์‹ฌ ์„œ๋น„์Šค์™€ next/image

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ํ™ˆ ๊ฒŒ์‹œ๋ฌผ, ๊ฒ€์ƒ‰ ํ”ผ๋“œ, ํˆฌํ‘œ ๊ธฐ๋Šฅ, ํ”„๋กœํ•„ ๋“ฑ ์ด๋ฏธ์ง€๊ฐ€ ์„œ๋น„์Šค ๊ฒฝํ—˜์˜ ์ค‘์‹ฌ์ด ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์„œ๋น„์Šค์—์„œ๋Š” ๋‹จ์ˆœํžˆ ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์„ ๋„˜์–ด ์–ด๋–ป๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ์–ธ์ œ ๋กœ๋”ฉํ•˜๋ฉฐ ์–ด๋–ค ํฌ๊ธฐ๋กœ ์ œ๊ณตํ•˜๋Š”์ง€๊ฐ€ ๊ณง ์„ฑ๋Šฅ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ขŒ์šฐํ•ฉ๋‹ˆ๋‹ค. Next.js์˜ next/image๋Š” ๋‹จ์ˆœํ•œ ์ด๋ฏธ์ง€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ์ด๋ฏธ์ง€ ์ „๋‹ฌ ์ „๋ฐ˜์„ ํ”„๋ ˆ์ž„์›Œํฌ ์ฐจ์›์—์„œ ์ตœ์ ํ™”ํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด

  • ๋””๋ฐ”์ด์Šค ๋ฐ ๋ทฐํฌํŠธ์— ๋งž๋Š” ์ด๋ฏธ์ง€ ์ž๋™ ์ œ๊ณต
  • Webp / AVIF ๊ธฐ๋ฐ˜์˜ ์ž๋™ ํฌ๋งท ๋ณ€ํ™˜
  • Lazy loading ๊ธฐ๋ณธ ์ ์šฉ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์ตœ์†Œํ™”
  • ์ด๋ฏธ์ง€ ์˜์—ญ ์„ ํ™•๋ณด๋ฅผ ํ†ตํ•œ ๋ ˆ์ด์•„์›ƒ ์•ˆ์ •์„ฑ ๋ณด์žฅ

์ด์™€ ๊ฐ™์€ ์ตœ์ ํ™”๊ฐ€ ๋ณ„๋„์˜ ์ถ”๊ฐ€ ์„ค์ • ์—†์ด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, ๋™์ผํ•œ ์ด๋ฏธ์ง€๊ฐ€ ํ”ผ๋“œ ๊ฒŒ์‹œ๋ฌผ, ์ƒ์„ธ ๊ฒŒ์‹œ๋ฌผ, ํ”„๋กœํ•„ ๋“ฑ ์—ฌ๋Ÿฌ ํฌ๊ธฐ์™€ ๋งฅ๋ฝ์—์„œ ๋ฐ˜๋ณต ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์กฐ์—์„œ ์ผ๊ด€๋œ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ๊ด€๋ฆฌ ๋น„์šฉ์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

React + Vite ํ™˜๊ฒฝ์—์„œ๋„ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๋Š” ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋‚˜ ๋ฆฌ์‚ฌ์ด์ง•, ํฌ๋งท ๋ณ€ํ™˜, lazy loading ๋“ฑ์˜ ๋กœ์ง์ด ์ปดํฌ๋„ŒํŠธ๋ณ„ ํ˜น์€ ์œ ํ‹ธ ๋‹จ์œ„๋กœ ๋ถ„์‚ฐ๋˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.


2๏ธโƒฃ Language โ€” TypeScript

๊ตฌ๋ถ„ JavaScript (Dynamic) TypeScript (Static)
์ปดํŒŒ์ผ ๋ฐฉ์‹ ์ธํ„ฐํ”„๋ฆฌํ„ฐ(์‹คํ–‰ ์‹œ ํ•ด์„) ํŠธ๋žœ์ŠคํŒŒ์ผ(์ปดํŒŒ์ผ ํ›„ JS๋กœ ๋ณ€ํ™˜)
์—๋Ÿฌ ๊ฐ์ง€ ์‹œ์  ๋ธŒ๋ผ์šฐ์ € ์‹คํ–‰ ์ค‘ (Runtime) ์ปดํŒŒ์ผ ์‹œ์ ์—์„œ ์—๋Ÿฌ ๊ฐ์ง€
๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ •์˜ ์•”๋ฌต์  (์ฃผ์„์— ์˜์กด) ๋ช…์‹œ์  (Interface / Type ์ •์˜)
๊ฐœ๋ฐœ ๋„๊ตฌ ์ง€์› ์ œํ•œ์  (์ง์ ‘ ํ™•์ธ ํ•„์š”) ๊ฐ•๋ ฅํ•œ ์ž๋™ ์™„์„ฑ ๋ฐ ๊ฐ€์ด๋“œ
์œ ์ง€๋ณด์ˆ˜ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์งˆ์ˆ˜๋ก ๊ด€๋ฆฌ ์–ด๋ ค์›€ ์ฝ”๋“œ ์•ˆ์ •์„ฑ์ด ๋†’๊ณ  ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด
์‹คํ–‰ ํ™˜๊ฒฝ ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ JS๋กœ ๋ณ€ํ™˜ ํ›„ ์‹คํ–‰ ๊ฐ€๋Šฅ
  1. ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๋ฌธ์„œํ™” : FITCHECK์˜ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด๊ตฌ์กฐ๋Š” ์œก์•ˆ์œผ๋กœ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. TypeScript๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ์ฝ”๋“œ๋กœ ๋ฌธ์„œํ™”ํ•จ์œผ๋กœ์จ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ๋ฐ ์‹ ๋ขฐ๋„ ํ™•๋ณด : ์ƒํƒœ ๋ณ€๊ฒฝ ๋นˆ๋„๊ฐ€ ๋†’์€ ์„œ๋น„์Šค ํŠน์„ฑ์ƒ ์ž˜๋ชป๋œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ์น˜๋ช…์ ์ธ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ํƒ€์ž… ์ฒดํฌ๋ฅผ ๊ฐ•์ œํ•จ์œผ๋กœ์จ ํ”„๋ก ํŠธ์—”๋“œ์™€ ์„œ๋ฒ„ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ทœ๊ฒฉ์„ ์ผ์น˜์‹œํ‚ค๊ณ  ๋ฐ์ดํ„ฐ ์‹ ๋ขฐ๋„๋ฅผ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ๋Œ€๊ทœ๋ชจ ๋ฆฌํŒฉํ„ฐ๋ง์˜ ์•ˆ์ •์„ฑ : ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์„œ๋ฒ„ ์‘๋‹ต ํ˜•์‹์ด ๋ฐ”๋€” ๋•Œ, TypeScript๋Š” ์ˆ˜์ •์ด ํ•„์š”ํ•œ ๋ชจ๋“  ๊ณณ์„ ์—๋Ÿฌ๋กœ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ์„ ํš๊ธฐ์ ์œผ๋กœ ๋‚ฎ์ถ”๋ฉฐ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

3๏ธโƒฃ State Architecture

Server State โ€” TanStack Query

TanStack Query๋Š” ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํšจ์œจ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด, ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ๋กœ๋”ฉ, ์—๋Ÿฌ์ฒ˜๋ฆฌ, ์บ์‹ฑ, ๋ฆฌํŒจ์น˜ ๋“ฑ์˜ ๊ณผ์ •์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

  1. ์ง€๋Šฅํ˜• ์บ์‹ฑ

    ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด๋‘ก๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ํŽ˜์ด์ง€์— ๊ฐ”๋‹ค๊ฐ€ ๋‹ค์‹œ ๋Œ์•„์™€๋„ ์„œ๋ฒ„์— ๋˜ ๋ฌผ์–ด๋ณด์ง€ ์•Š๊ณ  ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ™”๋ฉด์ด ๊นœ๋นก์ด์ง€ ์•Š๊ณ  ์•„์ฃผ ๋น ๋ฅด๊ฒŒ ๋А๊ปด์ง€๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

  2. ์ƒํƒœ ์ž๋™ ๊ด€๋ฆฌ

  • isLoading : ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘์ธ์ง€?
  • isError: ์„œ๋ฒ„๊ฐ€ ์ฃฝ์—ˆ๊ฑฐ๋‚˜ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋Š”์ง€?
  • data : ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€? ์ด ๊ฐ’๋“ค์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๋‹จ์ˆœํ•ด์ง‘๋‹ˆ๋‹ค.
  1. ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

    ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒํ•œ ๋ฐ์ดํ„ฐ์ธ์ง€ ์Šค์Šค๋กœ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๋ž˜๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋ฅด๋Š” ์‚ฌ์ด์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์™€ ํ™”๋ฉด์„ ์ตœ์‹  ์ƒํƒœ๋กœ ๊ฐˆ์•„ ๋ผ์›Œ์ค๋‹ˆ๋‹ค.

Cache Strategy โ€” Next.js Cache vs TanStack Query Cache

FITCHECK์€ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ๊ณผ ํด๋ผ์ด์–ธํŠธ์˜ ์ฆ‰๊ฐ์ ์ธ ์‘๋‹ต์„ฑ์„ ๋™์‹œ์— ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•ด Next.js์™€ TanStack Query์˜ ์บ์‹œ๋ฅผ ์ƒํ˜ธ ๋ณด์™„์ ์œผ๋กœ ๋ฐฐ์น˜ํ•˜๋Š” ์ „๋žต์„ ์ƒ๊ฐํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

๊ตฌ๋ถ„ Next.js Server Cache TanStack Query (Client)
์œ„์น˜ ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ / ํŒŒ์ผ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ
๋ชฉ์  ์™ธ๋ถ€ API/DB ์žฌํ˜ธ์ถœ ๋ฐฉ์ง€ UX ์ค‘์‹ฌ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”
๊ด€๋ฆฌ revalidateTag ๊ธฐ๋ฐ˜ (์„œ๋ฒ„ ์ค‘์‹ฌ) staleTime, gcTime (ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ)
๋ฐ์ดํ„ฐ ๊ณตํ†ต ํ”ผ๋“œ, ์ดˆ๊ธฐ ์ง„์ž… ๋ฐ์ดํ„ฐ ๊ฐœ์ธํ™” ๋ฐ์ดํ„ฐ, ์ƒํ˜ธ์ž‘์šฉ ๊ฒฐ๊ณผ

์™œ ๋‘ ์บ์‹œ๋ฅผ ๋ณ‘ํ–‰ํ•˜๋Š”๊ฐ€?

  1. ์ธํ„ฐ๋ž™์…˜ ์•ˆ์ •์„ฑ (๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ)

    ํˆฌํ‘œ๋‚˜ ์ข‹์•„์š”์ฒ˜๋Ÿผ ๋นˆ๋ฒˆํ•œ ์ธํ„ฐ๋ž™์…˜์ด ๋ฐœ์ƒํ•˜๋Š” ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ ์„œ๋ฒ„ ์•ก์…˜๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋„คํŠธ์›Œํฌ ์ง€์—ฐ์ด UI์— ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. TanStack Query๋ฅผ ํ†ตํ•ด ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ๋ฅผ ์ ์šฉํ•จ์œผ๋กœ์จ ์„œ๋ฒ„ ์‘๋‹ต ์ „์— UI๋ฅผ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜ํ•˜๊ณ  ์‹คํŒจ ์‹œ์—๋งŒ ๋กค๋ฐฑํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ๋กœ์ง์˜ ํ‘œ์ค€ํ™”

    Next.js๋Š” ์„œ๋ฒ„ ๋‹จ์˜ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์— ๊ฐ•์ ์ด ์žˆ์ง€๋งŒ ๋ฌดํ•œ ์Šคํฌ๋กค ๊ฐ™์€ ๋™์ ์ธ ๋ฐ์ดํ„ฐ ๋ณ‘ํ•ฉ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์ œ์–ด์—๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. useInfiniteQuery๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€ ๋ˆ„์ ๊ณผ ์บ์‹œ ์‚ญ์ œ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ๊ด€๋ฆฌํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ์บ์‹œ : ์ฒซ ์ง„์ž… ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ์ฆ‰์‹œ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋น ๋ฅธ LCP๋ฅผ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ ์บ์‹œ : ํŽ˜์ด์ง€ ์ด๋™์ด๋‚˜ ํƒญ ์ „ํ™˜ ํ›„ ๋ณต๊ท€ ์‹œ, ์„œ๋ฒ„ ์š”์ฒญ ์—†์ด ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋ณด์—ฌ์ฃผ๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ๋งŒ ์ตœ์‹ ํ™”๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ ๊นœ๋นก์ž„ ์—†๋Š” ํ™”๋ฉด ์ „ํ™˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Client State โ€” Zustand

Zustand๋Š” Next.js ์•ˆ์—์„œ ์„œ๋ฒ„์™€ ์ „ํ˜€ ์ƒ๊ด€์—†๋Š” ํด๋ผ์ด์–ธํŠธ UI ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๊ตฌ๋ถ„ Redux Zustand
๋ณต์žก๋„ Action, Reducer, Store ๋“ฑ ๊ตฌ์กฐ ๋ณต์žก ๋‹จ์ผ Store ์ค‘์‹ฌ์˜ ์ง๊ด€์  ๊ตฌ์กฐ
๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ๋งค์šฐ ๋งŽ์Œ (์ฝ”๋“œ ๋น„๋Œ€ํ™”) ๊ฑฐ์˜ ์—†์Œ (ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ๊ฐ„๊ฒฐํ•˜๊ฒŒ)
๋ฒˆ๋“ค ํฌ๊ธฐ ๋ฌด๊ฑฐ์›€ (๋Œ€๊ทœ๋ชจ ํ”„๋ ˆ์ž„์›Œํฌ) ๋งค์šฐ ๊ฐ€๋ฒผ์›€ (์ดˆ๊ฒฝ๋Ÿ‰ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)
ํ•™์Šต ๊ณก์„  ๋†’์Œ (๊ฐœ๋… ์ดํ•ด์— ์‹œ๊ฐ„ ์†Œ์š”) ๋งค์šฐ ๋‚ฎ์Œ (Hooks ๊ธฐ๋ฐ˜์œผ๋กœ ์ง๊ด€์ )
  1. UI ์ƒํƒœ ๊ด€๋ฆฌ์— ์ตœ์ ํ™”๋œ ๊ฐ€๋ฒผ์›€

    ๋ณธ ํ”„๋กœ์ ํŠธ์˜ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๋Š” ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ์— ๋น„ํ•ด ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค. Redux์˜ ๋ฌด๊ฑฐ์šด ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋„์ž…ํ•˜์—ฌ ์ฝ”๋“œ ๋ณต์žก๋„๋ฅผ ๋†’์ด๊ธฐ ๋ณด๋‹ค, ํ•„์š”ํ•œ ์ƒํƒœ๋งŒ Hook ํ˜•ํƒœ๋กœ ์ฆ‰์‹œ ์ƒ์„ฑํ•˜๊ณ  ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š” Zustand๊ฐ€ ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ ์ธก๋ฉด์—์„œ ์••๋„์ ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

  2. ์œ ์—ฐํ•œ ์ƒํƒœ ๊ตฌ๋…๊ณผ ์„ฑ๋Šฅ ์ตœ์ ํ™”

    Redux๋Š” ์ „์ฒด ์ƒํƒœ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์‹ ๊ฒฝ ์“ธ ๋ถ€๋ถ„์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Zustand๋Š” Selector ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ํŠน์ • ์ƒํƒœ๊ฐ’๋งŒ ์„ ํƒ์ ์œผ๋กœ ๊ตฌ๋…ํ•˜๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ž…๋‹ˆ๋‹ค. ์ด ๋•๋ถ„์— ๊ด€๋ จ ์—†๋Š” ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋”๋ผ๋„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์•„์„œ ์„ฑ๋Šฅ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•œ ๋ชจ๋ฐ”์ผ ์›น ํ™˜๊ฒฝ์—์„œ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


4๏ธโƒฃ Form & Validation

React Hook Form & Zod

React Hook Form

React์—์„œ ํผ ์ƒํƒœ๋ฅผ ์ตœ์†Œํ•œ์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํผ ์ „์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•œ ์„ฑ๋Šฅ ์ตœ์ ํ™” : ๊ธฐ์กด React์˜ useState ๋ฐฉ์‹์€ ๊ธ€์ž ํ•˜๋‚˜๋ฅผ ์ž…๋ ฅํ•  ๋•Œ ๋งˆ๋‹ค ์ „์ฒด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜์–ด ํ•„๋“œ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ํƒ€์ดํ•‘ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. React Hook Form์€ ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ ๋ฐฉ์‹์„ ํ™œ์šฉํ•ด ์ž…๋ ฅ ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•˜๋ฉฐ ๋Œ€๊ทœ๋ชจ ํผ์—์„œ๋„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋Š๊น€ ์—†๋Š” ์ž…๋ ฅ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ตฌ๋… ๊ธฐ๋ฐ˜์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ : ํŠน์ • ํ•„๋“œ์˜ ๊ฐ’๋งŒ ๊ฐ์‹œํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋Š” ๊ธฐ๋Šฅ์ด ๋งค์šฐ ํšจ์œจ์ ์œผ๋กœ ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™”๋ฉด ์ „์ฒด๋ฅผ ์ƒˆ๋กœ ๊ทธ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ํŠน์ • ์ž…๋ ฅ๊ฐ’์— ๋”ฐ๋ฅธ ๋™์ ์ธ UI ๋ณ€ํ™”๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ ๊ด€๋ฆฌ์™€ ๋ณต์žกํ•œ UI ๊ตฌํ˜„์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Zod

Typescript ๊ธฐ๋ฐ˜ ์Šคํ‚ค๋งˆ ์„ ์–ธ ๋ฐ ๋Ÿฐํƒ€์ž„ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ๊ธฐ์กด์˜ ์ˆ˜๋™ ํƒ€์ž… ์ •์˜ ๋ฐฉ์‹์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ํƒ€์ž… ์„ ์–ธ์ด ๋™๊ธฐํ™”๋˜์ง€ ์•Š์•„ ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ์˜ ์ฃผ์š” ์›์ธ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Zod๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์˜ ์Šคํ‚ค๋งˆ์—์„œ ํƒ€์ž… ์ถ”๋ก ๊ณผ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ ์ •์  ํƒ€์ž… ์‹œ์Šคํ…œ๊ณผ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์‚ฌ์ด์˜ ๊ฐ„๊ทน์„ ์™„๋ฒฝํžˆ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” API ์‘๋‹ต์ด๋‚˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋“ฑ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ž…๋˜๋Š” ์ง€์ ์—์„œ ๊ฐ•๋ ฅํ•œ ๋ฐฉ์–ด๋ง‰ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ช…๋ นํ˜• ์กฐ๊ฑด๋ฌธ์œผ๋กœ ํฉ์–ด์ ธ ์žˆ๋˜ ๊ฒ€์ฆ ๋กœ์ง์„ ๋‹จ์ผ ์Šคํ‚ค๋งˆ ์ •์˜๋กœ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹ ๊ธฐ๋ฐ˜์˜ ์„ ์–ธ์  ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ทœ๊ฒฉ์„ ์ฝ”๋“œ ์ž์ฒด๋กœ ๋ฌธ์„œํ™”ํ–ˆ์œผ๋ฉฐ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™ ๋ณ€๊ฒฝ ์‹œ ํ•ด๋‹น ์Šคํ‚ค๋งˆ๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ํƒ€์ž…๊ณผ ๊ฒ€์ฆ๋กœ์ง์ด ์ฆ‰์‹œ ๋™๊ธฐํ™”๋˜๋Š” ๋†’์€ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ™•๋ณดํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ž…๋ ฅ ํผ๊ณผ ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์ด ๋นˆ๋ฒˆํ•œ ์„œ๋น„์Šค๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” React Hook Form์„ ์‚ฌ์šฉํ•ด ํผ ์ƒํƒœ๋ฅผ ๊ฐ€๋ณ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ , Zod๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ์™€ ๊ฒ€์ฆ ๊ทœ์น™์„ ๋ช…ํ™•ํžˆ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Next.js ํ™˜๊ฒฝ์—์„œ๋Š” ๋™์ผํ•œ Zod ์Šคํ‚ค๋งˆ๋ฅผ ์„œ๋ฒ„์—์„œ๋„ ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ํด๋ผ์ด์–ธํŠธ UX์™€ ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋™์‹œ์— ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


5๏ธโƒฃ Styling โ€” Tailwind CSS

  • Tailwind css๋Š” ๋นŒ๋“œ ํƒ€์ž„์— ์ •์  CSS ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋ชจ๋“  ์Šคํƒ€์ผ ๋กœ์ง์ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ํ™˜๊ฒฝ๊ณผ ์ถฉ๋Œ ์—†์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Next.js์˜ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๋ฐ ์ •์  ์žฌ์ƒ์„ฑ ๊ณผ์ •์—์„œ ์Šคํƒ€์ผ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ์ถ”๊ฐ€ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์•„ ์ดˆ๊ธฐ์‘๋‹ต์†๋„๋ฅผ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์Šคํƒ€์ผ ์‹œํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์‹คํ–‰ ์‹œ์ ์— ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ธฐ ๋–„๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ๋ถ€๋‹ด์„ ์ค„์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ด๋ฏธ์ง€ ์ฝ˜ํ…์ธ ๊ฐ€ ์ค‘์‹ฌ์ธ FITCHECK ์„œ๋น„์Šค์—์„œ ์Šคํƒ€์ผ ์—ฐ์‚ฐ ๋น„์šฉ์„ ์ œ๊ฑฐํ•จ์œผ๋กœ์จ ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ ์‚ฌ์–‘์— ๊ด€๊ณ„์—†์ด ๋ถ€๋“œ๋Ÿฌ์šด ๋ ˆ์ด์•„์›ƒ ๋žœ๋”๋ง๊ณผ ์‹œ๊ฐ์  ์•ˆ์ •์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋น ๋ฅธ UI ๋ฐ˜๋ณต ์ฃผ๊ธฐ๋ฅผ ์‚ฌ์ง„ ํ”„๋กœ์ ํŠธ์—์„œ ๋””์ž์ธ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ๋ถˆํ•„์š”ํ•œ ์ค‘๋ณต CSS ์ƒ์„ฑ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ์ „์ฒด ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Styled-components ๋ฐฐ์ œ ์ด์œ 

  • ์ƒํƒœ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ JS CPU ์ ์œ ์œจ์ด ์ƒ์Šนํ•ฉ๋‹ˆ๋‹ค. ์ƒํ˜ธ์ž‘์šฉ์ด ์žฆ๊ณ  ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” FITCHECK ์ธํ„ฐํŽ˜์ด์Šค ํŠน์„ฑ์ƒ ์ด๋Ÿฌํ•œ ๋Ÿฐํƒ€์ž„ ์Šคํƒ€์ผ ์—ฐ์‚ฐ์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์˜ ๋ฏธ์„ธํ•œ ๋ฒ„๋ฒ…์ž„์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML๊ณผ ํด๋ผ์ด์–ธํŠธ ์Šคํƒ€์ผ ์‹œํŠธ๋ฅผ ๋™๊ธฐํ™” ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ถ”๊ฐ€์ ์ธ ๋น„์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์  ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์†๋„๋ฅผ ๊ทน๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ •์  ์Šคํƒ€์ผ๋ง ๋ฐฉ์‹์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

โœ… ํ•ต์‹ฌ ๊ธฐ์ˆ ๋ณ„ ๋ฒ„์ „ ์„ ํƒ ๊ทผ๊ฑฐ

Next.js (App Router) ^16.x๋ฅผ ์„ ํƒํ•œ ์ด์œ 

๊ตฌ๋ถ„ Next.js 15 Next.js 16
๊ธฐ๋ณธ ๋ฒˆ๋“ค๋Ÿฌ Webpack Turbopack (๊ธฐ๋ณธ)
React ๋ฒ„์ „ React 18 React 19
๋ Œ๋”๋ง ์ตœ์ ํ™” ๊ฐœ๋ฐœ์ž ์ˆ˜๋™ ์ตœ์ ํ™” React Compiler ์ž๋™ ์ตœ์ ํ™”
Prefetch ์ „๋žต ํŽ˜์ด์ง€ ๋‹จ์œ„ Incremental Prefetching

1. ๋ฒˆ๋“ค๋Ÿฌ ๊ด€์ : Webpack -> Turbopack

Next.js 15๊นŒ์ง€๋Š” Webpack์„ ๊ธฐ๋ณธ ๋ฒˆ๋“ค๋Ÿฌ๋กœ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. Webpack์€ ์•ˆ์ •์ ์ด์ง€๋งŒ ๋ชจ๋“ˆ ๊ทธ๋ž˜ํ”„ ์ „์ฒด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ ๋‹จ๊ณ„์—์„œ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ๋นŒ๋“œ ์†๋„๊ฐ€ ์ ์ง„์ ์œผ๋กœ ๋А๋ ค์ง€๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, Next.js 16๋ฒ„์ „์—์„œ์˜ Turbopack์€ Rust ๊ธฐ๋ฐ˜์˜ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ๋น ๋ฅธ ๋นŒ๋“œ ์†๋„๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด Webpack์ด Javascript๋กœ ์ž‘์„ฑ๋˜์–ด ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด์—ˆ๋˜ ๋ฐ˜๋ฉด, Turbopack์€ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ปดํŒŒ์ผ๊ณผ ๋ฒˆ๋“ค๋ง์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด ์†๋„๋ฉด์—์„œ ์ฐจ์ด๋ฅผ ๋ณด์ธ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

2. ๋ Œ๋”๋ง ์ตœ์ ํ™” ๊ด€์  : ์ˆ˜๋™ ์ตœ์ ํ™” -> React Compiler

Next.js 15๊นŒ์ง€๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด useMemo, useCallback, React.memo ๋“ฑ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์„ค๊ณ„ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ฝ”๋“œ ๋ณต์žก๋„ ์ฆ๊ฐ€, ๊ณผ๋„ํ•œ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋˜๋Š” ๋ˆ„๋ฝ์œผ๋กœ ์ธํ•œ ์„ฑ๋Šฅ ๋ถˆ์•ˆ์ •์„ฑ ์ด๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. Next.js 16์€ React 19๊ธฐ๋ฐ˜ React Compiler๋ฅผ ๊ธฐ๋ณธ ์ง€์›ํ•˜๋ฉฐ, ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์ž๋™์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ์žฌ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

3. ๋„คํŠธ์›Œํฌ ๊ด€์  : ํŽ˜์ด์ง€ ๋‹จ์œ„ prefetch -> Incremental Prefetching

Next.js 15์˜ prefetch๋Š” ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ๋™์ž‘ํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ์ง„์ž…ํ•˜์ง€ ์•Š๋”๋ผ๊ณ  ํ•ด๋‹น ํŽ˜์ด์ง€ ์ „์ฒด ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฏธ๋ฆฌ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๊ตฌ์กฐ์˜€์Šต๋‹ˆ๋‹ค. Next.js 16์˜ Incremental Prefetching์€ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•„์š”ํ•œ ๋‹จ์œ„๋งŒ ์ ์ง„์ ์œผ๋กœ prefetchํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ๋Ÿ‰ ๊ฐ์†Œ๋˜๋ฉฐ ํด๋ฆญ ์ง์ „ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋งŒ ์ค€๋น„๋ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ์ „ํ™˜ ์ฒด๊ฐ ์†๋„๋ฅผ ์•ˆ์ •์ ์ด๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.


TypeScript ^5.x ์„ ํƒ ์ด์œ 

๊ตฌ๋ถ„ TypeScript 4.x TypeScript 5.x
์ปดํŒŒ์ผ ์„ฑ๋Šฅ ๋ณดํ†ต ๋” ๋น ๋ฆ„
ํƒ€์ž… ์ฒดํฌ ์†๋„ ํŒŒ์ผ ์ˆ˜ ์ฆ๊ฐ€ ์‹œ ๋А๋ ค์ง ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์•ˆ์ •์ 
ํƒ€์ž… ์ถ”๋ก  ์ •ํ™•๋„ ์ œํ•œ์  ๋” ์ •๊ตํ•จ
ํƒ€์ž… ๋‹จ์–ธ(as) ์‚ฌ์šฉ ์ž์ฃผ ํ•„์š” ์‚ฌ์šฉ ๋นˆ๋„ ๊ฐ์†Œ
์ œ๋„ค๋ฆญ ์ถ”๋ก  ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋ถˆ์™„์ „ ๊ฐœ์„ ๋จ
์กฐ๊ฑด๋ถ€ ํƒ€์ž… ์ฒ˜๋ฆฌ ๋ณต์žกํ• ์ˆ˜๋ก ๋ถˆ์•ˆ์ • ์ •ํ™•๋„ ํ–ฅ์ƒ
IDE ๋ฐ˜์‘ ์†๋„ ํ”„๋กœ์ ํŠธ ์ปค์งˆ์ˆ˜๋ก ์ €ํ•˜ ์ž๋™์™„์„ฑยท์—๋Ÿฌ ํ‘œ์‹œ ๊ฐœ์„ 

TypeScript 4.x์—์„œ๋„ ๊ธฐ๋ณธ์ ์ธ ํƒ€์ž… ์•ˆ์ •์„ฑ์€ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ํŒŒ์ผ ์ˆ˜ ์ฆ๊ฐ€์— ๋”ฐ๋ฅธ ํƒ€์ž… ์ฒดํฌ ์†๋„ ์ €ํ•˜, ๋ณต์žกํ•œ ์ œ๋„ค๋ฆญ ๋ฐ ์กฐ๊ฑด๋ถ€ ํƒ€์ž… ์‚ฌ์šฉ ์‹œ ํƒ€์ž… ์ถ”๋ก  ํ•œ๊ณ„, ์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•œ ์žฆ์€ as ํƒ€์ž… ๋‹จ์–ธ ์‚ฌ์šฉ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์ƒ์‚ฐ์„ฑ์„ ๋–จ์–ด๋œจ๋ฆด ๋ฟ ์•„๋‹ˆ๋ผ, ํƒ€์ž… ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์‹ ๋ขฐ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ์š”์ธ์ด ๋ฉ๋‹ˆ๋‹ค.

TypeScript 5.x๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ดˆ์ ์„ ๋งž์ถ˜ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ์„ฑ๋Šฅ๊ณผ ํƒ€์ž… ์ถ”๋ก  ์ •ํ™•๋„๊ฐ€ ์ „๋ฐ˜์ ์œผ๋กœ ํ–ฅ์ƒ๋˜์–ด, ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ์ปค์ง€๋”๋ผ๋„ ํƒ€์ž… ์ฒดํฌ ์†๋„์™€ IDE ๋ฐ˜์‘์„ฑ์ด ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ํƒ€์ž… ์˜ค๋ฅ˜๋ฅผ ๋Ÿฐํƒ€์ž„ ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋” ๋งŽ์ด ์‚ฌ์ „์— ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ถˆํ•„์š”ํ•œ ํƒ€์ž… ๋‹จ์–ธ ์‚ฌ์šฉ์ด ์ค„์–ด๋“ค์–ด ์ฝ”๋“œ์˜ ์‹ ๋ขฐ์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์ด ํ•จ๊ป˜ ๊ฐœ์„ ๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ TypeScript 5.x๋Š” React 19์™€ Next.js 16์˜ ํƒ€์ž… ๊ตฌ์กฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ํ”„๋ ˆ์ž„์›Œํฌ ํ™˜๊ฒฝ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž… ์ถฉ๋Œ์ด ์ค„์–ด๋“ค๊ณ , ํ”„๋ ˆ์ž„์›Œํฌ ์—…๋ฐ์ดํŠธ์— ๋”ฐ๋ฅธ ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ๋„ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FITCHECK๋Š” ํˆฌํ‘œ, ํŒ”๋กœ์šฐ, ๊ฒŒ์‹œ๋ฌผ ๋“ฑ ์„œ๋กœ ๊ฐ•ํ•˜๊ฒŒ ์—ฐ๊ฒฐ๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ํƒ€์ž… ์ •ํ™•๋„๊ฐ€ ๊ณง ๊ธฐ๋Šฅ ์•ˆ์ •์„ฑ๊ณผ ์ง๊ฒฐ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ๋„ ํƒ€์ž… ์‹œ์Šคํ…œ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ TypeScript 5.x๋Š” ํ™•์žฅ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์žฅ๊ธฐ์ ์œผ๋กœ ๊ณ ๋ คํ–ˆ์„ ๋•Œ ๊ฐ€์žฅ ํ•ฉ๋ฆฌ์ ์ธ ์„ ํƒ์ง€๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.


TanStack Query ^5.x ์„ ํƒ ์ด์œ 

๊ตฌ๋ถ„ v4 (์ด์ „) v5 (ํ˜„์žฌ)
์ธ์ž ์ „๋‹ฌ useQuery(key, fn, options) (ํ˜ผํ•ฉ ๊ฐ€๋Šฅ) useQuery({ ... }) (๊ฐ์ฒด๋งŒ ๊ฐ€๋Šฅ)
์บ์‹œ ์‚ญ์ œ ์‹œ๊ฐ„ cacheTime gcTime
๋กœ๋”ฉ ์ƒํƒœ๋ช… status: 'loading', isLoading status: 'pending', isPending
์„ฑ๊ณต/์‹คํŒจ ์ฝœ๋ฐฑ onSuccess, onError (useQuery ๋‚ด ์กด์žฌ) ์ œ๊ฑฐ๋จ (useEffect๋‚˜ ์ „์—ญ ์„ค์ • ๊ถŒ์žฅ)
Suspense useQuery(..., { suspense: true }) useSuspenseQuery() (์ „์šฉ ํ›…)
  1. API ๊ตฌ์กฐ ๋‹จ์ˆœํ™” : ๊ฐ์ฒด ๊ธฐ๋ฐ˜ ์ธ์ž ์ „๋‹ฌ Tanstack Query v4์—์„œ๋Š” key, fn, options๋ฅผ ํ˜ผํ•ฉ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด ํ›… ์‚ฌ์šฉ ๋ฐฉ์‹์ด ์ผ๊ด€๋˜๊ธฐ ์–ด๋ ต๊ณ  ์˜ต์…˜ ๋ˆ„๋ฝ์ด๋‚˜ ์ˆœ์„œ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์› ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, Tanstack Query v5์—์„œ๋Š” ๋ชจ๋“  ์˜ต์…˜์„ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ๋งŒ ์ „๋‹ฌํ•˜๋„๋ก ๊ฐ•์ œํ•˜์—ฌ ํ›… ์‚ฌ์šฉ ๋ฐฉ์‹์„ ํ†ต์ผํ•˜๊ณ  ์˜ต์…˜ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋ฉฐ ํƒ€์ž… ์ถ”๋ก ์„ ์•ˆ์ •ํ™”์‹œํ‚ต๋‹ˆ๋‹ค.

  2. ์บ์‹œ ์ƒ๋ช…์ฃผ๊ธฐ ๋ช…ํ™•ํ™” : cacheTime -> gcTime Tanstack Query v4์˜ cacheTime์€ ์–ธ์ œ ์บ์‹œ๊ฐ€ ์‚ญ์ œ๋˜๋Š”์ง€ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ๋‹จ์–ด์˜€์Šต๋‹ˆ๋‹ค. v5์˜ gcTime์€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋Œ€์ƒ์ด ๋˜๋Š” ์‹œ๊ฐ„์„ ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚ด์–ด ์บ์‹œ ์œ ์ง€ ์‹œ์ , ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๊ธฐ์ค€, ๋น„ํ™œ์„ฑ ์ฟผ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  3. ์ƒํƒœ ๋ช…๋ช… ๊ฐœ์„  : loading -> pending 'loading'์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„์˜ˆ ์—†๋Š” ์ƒํƒœ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ƒํƒœ ๋“ฑ ์ค‘์˜์ ์œผ๋กœ ์“ฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. v5์—์„œ๋Š” "์•„์ง ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š์•„ ๋Œ€๊ธฐ์ค‘"์ด๋ผ๋Š” ์˜๋ฏธ์ธ pending์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋” ์„ธ๋ถ„ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

  4. ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ ๋ถ„๋ฆฌ : ์„ฑ๊ณต ๋ฐ ์‹คํŒจ ์ฝœ๋ฐฑ ์ œ๊ฑฐ v4์—์„œ๋Š” useQuery ๋‚ด๋ถ€์— onSuccess, onError๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ์–ด ๋ฐ์ดํ„ฐ ํŒจ์นญ๊ณผ ๋ถ€์ˆ˜ํšจ๊ณผ๊ฐ€ ์„ž์ด๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. v5์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ฟผ๋ฆฌ๋กœ ๊ฐ€์ ธ์˜ค๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ ํ–‰๋™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋‚˜ ์ „์—ญ ์„ค์ •์—์„œ ์ฒ˜๋ฆฌํ•˜๋ผ๋Š” ์ฒ ํ•™์„ ๊ฐ•์ œํ•˜์—ฌ ์ฝ”๋“œ์˜ ์ผ๊ด€์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค.

  5. Suspense ์‚ฌ์šฉ์„ฑ ๊ฐœ์„  v4์—์„œ๋Š” ์˜ต์…˜ ์„ค์ •๋งŒ์œผ๋กœ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์กฐ๊ฑด ์กด์žฌํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์— ์•Œ๋ฆด ์ˆ˜ ์—†์–ด ๋ถˆํ•„์š”ํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ v5์˜ ์ „์šฉ ํ›…์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•  ๋•Œ๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹คํ–‰๋จ์„ ํƒ€์ž… ์ˆ˜์ค€์—์„œ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.


Zustand 4.x ์„ ํƒ ์ด์œ 

๊ตฌ๋ถ„ Zustand 3.x Zustand 4.x
์ตœ์‹  React ํ‘œ์ค€ ๋ ˆ๊ฑฐ์‹œ ํŒจํ„ด ํ˜ผ์žฌ useSyncExternalStore ๋„์ž…
์ƒํƒœ ์•ˆ์ •์„ฑ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง ์‹œ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ์œ„ํ—˜ Tearing(ํ™”๋ฉด ์ฐข์–ด์ง) ๋ฐฉ์ง€
TypeScript ๊ธฐ๋ณธ ์ˆ˜์ค€์˜ ํƒ€์ž… ์ง€์› ์ •๊ตํ•œ ํƒ€์ž… ์ถ”๋ก  ์‹œ์Šคํ…œ
์ตœ์ ํ™” ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ ๊ฐ€๋Šฅ Selector ์•ˆ์ •์„ฑ ๊ฐ•ํ™”
  1. React ์ตœ์‹  ํ‘œ์ค€ ์ค€์ˆ˜ : React 18๋ถ€ํ„ฐ ํ‘œ์ค€์ด ๋œ useSyncExternalStore๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ, React 19์˜ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง ํ™˜๊ฒฝ์—์„œ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ผฌ์ด์ง€ ์•Š๊ณ  ํ•ญ์ƒ ์ผ๊ด€๋œ ๊ฐ’์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
  2. ์•ˆ์ „ํ•œ ํƒ€์ž… ์‹œ์Šคํ…œ : 4๋ฒ„์ „์—์„œ ๊ฐ•ํ™”๋œ ํƒ€์ž… ์ถ”๋ก  ๊ธฐ๋Šฅ์€ React 19์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์ตœ์‹  TypeScript ํ™˜๊ฒฝ์—์„œ ๊ฐ•๋ ฅํ•œ ์•ˆ์ •์„ฑ์„ ์ œ๊ณตํ•˜๋ฉฐ ๊ฐœ๋ฐœ์ž์˜ ์‹ค์ˆ˜๋ฅผ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  3. ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ž๋™ํ™” : Selector์˜ ์•ˆ์ •์„ฑ์ด ๋Œ€ํญ ๊ฐœ์„ ๋˜์–ด ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ๋•Œ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ์ •ํ™•ํ•˜๊ฒŒ ๋‹ค์‹œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋Š” ์„ฑ๋Šฅ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•œ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ๋ณ„๋„์˜ ์ตœ์ ํ™” ์ž‘์—… ์—†์ด๋„ ์••๋„์ ์ธ ํผํฌ๋จผ์Šค๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

React Hook Form ^7.x ์„ ํƒ ์ด์œ 

๊ตฌ๋ถ„ React Hook Form 6.x React Hook Form 7.x
์„ค๊ณ„ ์ฒ ํ•™ ๊ธฐ๋Šฅ ์ค‘์‹ฌ ์„ฑ๋Šฅยท์ผ๊ด€์„ฑ ์ค‘์‹ฌ
๋ Œ๋”๋ง ๋ฐฉ์‹ ์ƒํƒœ ๋ณ€ํ™” ์‹œ ๋ฆฌ๋ Œ๋” ๊ฐ€๋Šฅ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ์ตœ์†Œํ™”
Controlled / Uncontrolled ํ˜ผํ•ฉ ์‚ฌ์šฉ Uncontrolled ์ค‘์‹ฌ ๋ช…ํ™•ํ™”
API ์ผ๊ด€์„ฑ ์ผ๋ถ€ ์˜ต์…˜ ํ˜ผ์žฌ API ๊ตฌ์กฐ ์ •๋ฆฌ ๋ฐ ๋‹จ์ˆœํ™”
Form State ๊ด€๋ฆฌ ์˜์กด๋„ ๋†’์Œ ๊ตฌ๋… ๊ธฐ๋ฐ˜ ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐ•ํ™”
์„ฑ๋Šฅ ์ตœ์ ํ™” ์ˆ˜๋™ ์ตœ์ ํ™” ํ•„์š” ๊ธฐ๋ณธ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ œ๊ณต
TypeScript ์ง€์› ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํƒ€์ž… ์ถ”๋ก  ์ •ํ™•๋„ ํ–ฅ์ƒ
๋Œ€๊ทœ๋ชจ Form ๋Œ€์‘ ์ปค์งˆ์ˆ˜๋ก ๊ด€๋ฆฌ ๋ถ€๋‹ด ๋ณต์žกํ•œ Form์—๋„ ์•ˆ์ •์ 

React Hook Form 6.x๋Š” ํผ ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ์ž์œ ๋„๊ฐ€ ๋†’์ง€๋งŒ,ํผ์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง๊ณผ Form State ์˜์กด ์ฆ๊ฐ€๋กœ ์ธํ•ด ์„ฑ๋Šฅ ์ €ํ•˜์™€ ๊ด€๋ฆฌ ๋ณต์žก๋„๊ฐ€ ํ•จ๊ป˜ ์ฆ๊ฐ€ํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. React Hook Form 7.x๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Form ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ๋ช…ํ™•ํžˆ ์ •๋ฆฌํ•˜๊ณ  ์„ฑ๋Šฅ ์ค‘์‹ฌ์œผ๋กœ ์žฌ์„ค๊ณ„๋œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ๊ฐ’ ๋ณ€๊ฒฝ ์‹œ ์ „์ฒด Form์ด ๋ฆฌ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„๋˜์–ด, ์ž…๋ ฅ ํ•„๋“œ๊ฐ€ ๋งŽ์€ ํ™”๋ฉด์—์„œ๋„ UI ๋ฐ˜์‘์„ฑ์ด ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

Form State๋ฅผ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ์„ ํƒ์ ์œผ๋กœ ๊ตฌ๋…ํ•˜๋„๋ก ๊ตฌ์กฐ๊ฐ€ ์ •๋ฆฌ๋˜์–ด, ์—๋Ÿฌ ํ‘œ์‹œ, validation ์ƒํƒœ, submit ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ๋“ฑ์˜ UI ๋กœ์ง์„ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TypeScript ํƒ€์ž… ์ถ”๋ก ์ด ๊ฐœ์„ ๋˜์–ด, ํ•„๋“œ ์ด๋ฆ„ ์˜คํƒ€๋‚˜ Form ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์˜ค๋ฅ˜๋ฅผ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์‚ฌ์ „์— ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ํšŒ์›๊ฐ€์ž…, ํ”„๋กœํ•„ ์ˆ˜์ •, ๊ฒŒ์‹œ๋ฌผ ์ž‘์„ฑ ๋“ฑ ํผ ๊ธฐ๋ฐ˜ ์ธํ„ฐ๋ž™์…˜์ด ์žฆ์€ ์„œ๋น„์Šค์—์„œ๋Š” ์ž…๋ ฅ ์ค‘ ์„ฑ๋Šฅ ์•ˆ์ •์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ข…ํ•ฉํ–ˆ์„ ๋•Œ, React Hook Form 7.x๋Š” ๋Œ€๊ทœ๋ชจ ํผ์—์„œ๋„ ์„ฑ๋Šฅ๊ณผ ๊ตฌ์กฐ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์„ ํƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.


Zod ^3.x ์„ ํƒ ์ด์œ 

๊ตฌ๋ถ„ Zod 2.x Zod 3.x
์„ค๊ณ„ ๋ฐฉํ–ฅ ๊ธฐ๋ณธ์ ์ธ ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ ํƒ€์ž… ์ค‘์‹ฌ ์Šคํ‚ค๋งˆ ์„ค๊ณ„
TypeScript ์—ฐ๋™ ์ œํ•œ์  Type Inference ๊ฐ•ํ™”
ํƒ€์ž… ์ถ”๋ก  ์ •ํ™•๋„ ๋ถ€๋ถ„์  ์ •ํ™•ํ•˜๊ณ  ์ผ๊ด€๋จ
๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ ๊ฐ€๋Šฅ ์ •๊ตํ•˜๊ณ  ์•ˆ์ •์ 
์—๋Ÿฌ ๊ตฌ์กฐ ๋‹จ์ˆœ ๋ฉ”์‹œ์ง€ ์ค‘์‹ฌ ๊ตฌ์กฐํ™”๋œ ์—๋Ÿฌ ์ •๋ณด
์ปค์Šคํ…€ ๊ฒ€์ฆ ๊ฐ€๋Šฅํ•˜๋‚˜ ๋ณต์žก ์ง๊ด€์ ์ธ refine/superRefine
Form ์—ฐ๋™ ๊ฐ€๋Šฅ RHF ๋“ฑ๊ณผ ์ž์—ฐ์Šค๋Ÿฌ์šด ์—ฐ๋™
API ์•ˆ์ •์„ฑ ๋ณ€๋™ ๊ฐ€๋Šฅ์„ฑ ์•ˆ์ •ํ™”๋œ API
๋Œ€๊ทœ๋ชจ ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ ๋ถ€๋‹ด ํ™•์žฅ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฐœ์„ 

Zod 2.x์—์„œ๋„ ๊ธฐ๋ณธ์ ์ธ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์€ ๊ฐ€๋Šฅํ–ˆ์ง€๋งŒ, ์Šคํ‚ค๋งˆ์™€ TypeScript ํƒ€์ž…์ด ์™„์ „ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š์•„ ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ํƒ€์ž… ๊ด€๋ฆฌ ๋น„์šฉ๊ณผ ๋ถˆ์ผ์น˜ ์œ„ํ—˜์ด ์ปค์ง€๋Š” ๊ตฌ์กฐ์˜€์Šต๋‹ˆ๋‹ค.

Zod 3.x๋Š” ์Šคํ‚ค๋งˆ ์ •์˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ๊ณผ TypeScript ํƒ€์ž… ์ถ”๋ก ์„ ๋™์‹œ์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์Šคํ‚ค๋งˆ๋กœ ์ž…๋ ฅ๊ฐ’ ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ, Form ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ถ”๋ก , API ์š”์ฒญ ๋ฐ ์‘๋‹ต ํƒ€์ž… ์ผ๊ด€์„ฑ์„ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด, ํ”„๋ก ํŠธ์—”๋“œ ์ „๋ฐ˜์—์„œ ๋‹จ์ผ ๊ธฐ์ค€์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ React Hook Form๊ณผ ๊ฒฐํ•ฉํ–ˆ์„ ๋•Œ ๊ฒ€์ฆ, ์—๋Ÿฌ ๊ด€๋ฆฌ, ์กฐ๊ฑด๋ณ„ Validation ๋กœ์ง์ด ์„ ์–ธ์ ์œผ๋กœ ์ •๋ฆฌ๋˜์–ด ํผ ๊ทœ๋ชจ๊ฐ€ ์ปค์ ธ๋„ ๊ตฌ์กฐ๊ฐ€ ๋ณต์žกํ•ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์„ฑ ๋•๋ถ„์— Zod 3.x๋Š” ์„œ๋น„์Šค๊ฐ€ ํ™•์žฅ๋ ์ˆ˜๋ก ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์•ˆ์ •์ ์œผ๋กœ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋Š” ์„ ํƒ์ง€๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.


โš ๏ธ **GitHub.com Fallback** โš ๏ธ