์ƒˆ๋กœ์šด React ์•ฑ ๋งŒ๋“ค๊ธฐ

React๋กœ ์ƒˆ๋กœ์šด ์•ฑ์ด๋‚˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋ ค๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์•ฑ์— ๊ธฐ์กด ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž˜ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ์ œ์•ฝ ์กฐ๊ฑด์ด ์žˆ๊ฑฐ๋‚˜, ์ž์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๊ฑฐ๋‚˜, React ์•ฑ์˜ ๊ธฐ๋ณธ ์‚ฌํ•ญ๋งŒ ๋ฐฐ์šฐ๋ ค๋Š” ๊ฒฝ์šฐ React ์•ฑ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ’€์Šคํƒ ํ”„๋ ˆ์ž„์›Œํฌ

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

์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค!

ํ’€์Šคํƒ ํ”„๋ ˆ์ž„์›Œํฌ์—๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค

์ด ํŽ˜์ด์ง€์˜ ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก ๋ Œ๋”๋ง(CSR), ๋‹จ์ผ ํŽ˜์ด์ง€ ์•ฑ(SPA), ์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ(SSG)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์•ฑ์€ ์„œ๋ฒ„ ์—†์ด CDN ๋˜๋Š” ์ •์  ํ˜ธ์ŠคํŒ… ์„œ๋น„์Šค์— ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ํ•ฉํ•œ ๊ฒฝ์šฐ ๊ฒฝ๋กœ๋ณ„๋กœ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์•ฑ์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‚˜์ค‘์— ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ ์•ฑ์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐœ๋ณ„ ๊ฒฝ๋กœ์—์„œ ์„œ๋ฒ„ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ „๋žต์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

Next.js (์•ฑ ๋ผ์šฐํ„ฐ)

Next.js์˜ ์•ฑ ๋ผ์šฐํ„ฐ๋Š” React์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜์—ฌ ํ’€ ์Šคํƒ React ์•ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

ํ„ฐ๋ฏธ๋„
npx create-next-app@latest

Next.js๋Š” Vercel์—์„œ ์œ ์ง€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Next.js ์•ฑ์„ ๋นŒ๋“œํ•ด์„œ Node.js, ๋„์ปค ์ปจํ…Œ์ด๋„ˆ, ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ…, ํ˜น์€ ์ž์ฒด ์„œ๋ฒ„์— ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js๋Š” ๋˜ํ•œ ์„œ๋ฒ„๊ฐ€ ํ•„์š”์—†๋Š” ์ •์  ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

React Router (v7)

React Router๋Š” React์—์„œ ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” ๋ผ์šฐํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ Vite์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‘œ์ค€ Web API๋ฅผ ๊ฐ•์กฐํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Ÿฐํƒ€์ž„๊ณผ ํ”Œ๋žซํผ์„ ์œ„ํ•œ ์ค€๋น„๋œ ๋ฐฐํฌ ํ…œํ”Œ๋ฆฟ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด React Router ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

ํ„ฐ๋ฏธ๋„
npx create-react-router@latest

React Router๋Š” Shopify์—์„œ ์œ ์ง€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Expo (๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์šฉ)

Expo๋Š” ๋„ค์ดํ‹ฐ๋ธŒ UI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ๋“œ๋กœ์ด๋“œ, iOS, ์›น์„ ์œ„ํ•œ ๋ฒ”์šฉ์•ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ๋ถ€๋ถ„์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” React Native SDK๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด Expo ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

ํ„ฐ๋ฏธ๋„
npx create-expo-app@latest

Expo๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, Expo ์ž์Šต์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

Expo๋Š” Expo (the company)์—์„œ ์œ ์ง€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Expo๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์€ ๋ฌด๋ฃŒ์ด๊ณ  ๊ตฌ๊ธ€์ด๋‚˜ ์• ํ”Œ ์Šคํ† ์–ด์— ์ œํ•œ์—†์ด ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Expo๋Š” ์ถ”๊ฐ€์ ์œผ๋กœ ์˜ตํŠธ์ธ ์œ ๋ฃŒ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ

ํ’€์Šคํƒ React ๋น„์ „์„ ํ–ฅํ•ด ๋‚˜์•„๊ฐ€๊ณ  ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ๋– ์˜ค๋ฅด๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • TanStack Start (Beta): TanStack Start๋Š” TanStack Router๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. Nitro๋‚˜ Vite์™€ ๊ฐ™์ด ์ „์ฒด ๋ฌธ์„œ SSR, ์ŠคํŠธ๋ฆฌ๋ฐ, ์„œ๋ฒ„ ํ•จ์ˆ˜, ๋ฒˆ๋“ค๋ง๊ณผ ๋งŽ์€ ์œ ์šฉํ•œ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • RedwoodJS: Redwood๋Š” ์‰ฝ๊ฒŒ ํ’€์Šคํƒ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์ „ํƒ‘์žฌ๋œ ํŒจํ‚ค์ง€์™€ ๊ตฌ์„ฑ์„ ๊ฐ€์ง„ ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ธฐ

React ํŒ€์˜ ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

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

์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ๋ฒ„ ์ „์šฉ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ํŒŒ์ผ์„ ์ฝ๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€ํ™”ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์ด ์ปดํฌ๋„ŒํŠธ๋Š” *์˜ค์ง* ์„œ๋ฒ„์—์„œ๋งŒ(ํ˜น์€ ๋นŒ๋“œ๋˜๋Š” ๋™์•ˆ๋งŒ) ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
async function Talks({ confId }) {
// 1. ์„œ๋ฒ„์—์„œ๋ผ๋ฉด ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด์™€ ๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API ์—”๋“œํฌ์ธํŠธ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
const talks = await db.Talks.findAll({ confId });

// 2. ๋ Œ๋”๋ง ๋กœ์ง์ด ์ถ”๊ฐ€๋˜๋”๋ผ๊ณ ๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ํฌ๊ฒŒ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
const videos = talks.map(talk => talk.video);

// 3. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋  ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
return <SearchableVideoList videos={videos} />;
}

Next.js์˜ App Router๋Š” Suspense์™€ ๋ฐ์ดํ„ฐ ์กฐํšŒ๋ฅผ ํ†ตํ•ฉํ•ฉ๋‹ˆ๋‹ค. React tree์—์„œ ์„œ๋กœ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๋กœ๋”ฉ ์ƒํƒœ(์˜ˆ: ์Šค์ผˆ๋ ˆํ†ค ํ”Œ๋ ˆ์ด์Šคํ™€๋”)๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

<Suspense fallback={<TalksLoading />}>
<Talks confId={conf.id} />
</Suspense>

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ Suspense๋Š” Next.js ๊ธฐ๋Šฅ์ด ์•„๋‹Œ React ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ˆ˜์ค€์—์„œ ์ด๋ฅผ ์ฑ„ํƒํ•˜๋ ค๋ฉด ์ฐธ์—ฌ์™€ ์‚ฌ์†Œํ•˜์ง€ ์•Š์€ ๊ตฌํ˜„ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Next.js App Router๋Š” ๊ฐ€์žฅ ์™„๋ฒฝํ•œ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. React ํŒ€์€ ์ฐจ์„ธ๋Œ€ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๋” ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฒˆ๋“ค๋Ÿฌ ๊ฐœ๋ฐœ์ž์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ

์•ฑ์— ๊ธฐ์กด ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž˜ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ์ œ์•ฝ ์กฐ๊ฑด์ด ์žˆ๊ฑฐ๋‚˜, ์ž์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๊ฑฐ๋‚˜, React ์•ฑ์˜ ๊ธฐ๋ณธ ์‚ฌํ•ญ์„ ๋ฐฐ์šฐ๋ ค๋Š” ๊ฒฝ์šฐ React ํ”„๋กœ์ ํŠธ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ž์‹ ๋งŒ์˜ ์†”๋ฃจ์…˜์„ ๊ตฌ์ถ•ํ•˜๋ ค๋ฉด, Vite, Parcel ๋˜๋Š” RSbuild์™€ ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ React ์•ฑ ๋งŒ๋“ค๊ธฐ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.


๋งŒ์•ฝ ์ด ํŽ˜์ด์ง€์— ํฌํ•จ๋˜๋Š”๋ฐ ๊ด€์‹ฌ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ž‘์„ฑ์ž๋ผ๋ฉด, ์ €ํฌ์—๊ฒŒ ์•Œ๋ ค์ฃผ์„ธ์š”.