[๐ค] Next.js App Router์์ Server Components์ Client Components ์ ๋๋ก ํ์ฉํ๊ธฐ
Next.js 13+ App Router ํ๊ฒฝ์์ Server Components์ Client Components์ ๊ฐ๋ , ์ฐจ์ด์ , ๊ทธ๋ฆฌ๊ณ ์ค์ฉ์ ์ธ ํ์ฉ ์ ๋ต์ ์์ธํ ์์๋ณด๊ณ , ์ฑ๋ฅ ์ต์ ํ์ ๊ฐ๋ฐ ํจ์จ์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๊ณต์ ํด์.
์ ๋ณด
Next.js 13+ App Router์ ํต์ฌ์ธ Server Components์ Client Components๋ฅผ ์ ๋๋ก ์ดํดํ๊ณ ํ์ฉํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ๊ณผ ๊ฐ๋ฐ ๊ฒฝํ์ ๊ทน๋ํํ๋ ๋ฐฉ๋ฒ์ ํจ๊ป ํ๊ตฌํด์.
์ฐ๋ฆฌ๋ Server Components๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ๊ณ , ํ์ํ ๊ณณ์๋ง Client Components๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ ํ๋ ์ํคํ ์ฒ๋ฅผ ๊ตฌ์ถํ๋ ์ ๋ต์ ๋ฐฐ์๋ณผ ๊ฑฐ์์.
๐ค ๋ฌธ์ /๋ฐฐ๊ฒฝ
0๏ธโฃ ์ ์ด ์ฃผ์ ๋ฅผ ๋ค๋ฃจ๋๊ฐ์?
Next.js 13๋ถํฐ ๋์
๋ App Router๋ ๊ธฐ์กด Pages Router์๋ ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ํจ๋ฌ๋ค์์ ์ ์ํ์ด์.
ํนํ Server Components๋ React์ ์๋ก์ด ๊ธฐ๋ฅ์ผ๋ก, ๋ฐฑ์๋ ๋ก์ง๊ณผ ํ๋ก ํธ์๋ UI๋ฅผ ํตํฉํ๋ ๊ฐ๋ ฅํ ๊ฐ๋ฅ์ฑ์ ์ด์ด์ฃผ์์ฃ .
ํ์ง๋ง ๋ง์ ๊ฐ๋ฐ์๋ถ๋ค์ด Server Components์ Client Components์ ์ ํํ ์ฐจ์ด์ , ๊ทธ๋ฆฌ๊ณ ์ธ์ ๋ฌด์์ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํด ํผ๋์ ๊ฒช๊ณ ๊ณ์ธ์.
์ด๋ฌํ ํผ๋์ ๋ถํ์ํ Client Component ์ฌ์ฉ์ผ๋ก ์ด์ด์ ธ Next.js๊ฐ ์ ๊ณตํ๋ ์ฑ๋ฅ ์ต์ ํ ์ด์ ์ ์ ๋๋ก ๋๋ฆฌ์ง ๋ชปํ๊ฒ ๋ง๋ค ์ ์์ด์.
1๏ธโฃ ๊ธฐ์กด ๋ฐฉ์์ ํ๊ณ (๋๋ ์คํด)
๊ธฐ์กด Pages Router๋ ๋ค๋ฅธ SPA(Single Page Application) ํ๋ ์์ํฌ์์๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ์์ ๋์ํ์ด์.
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ ์ฌ์ฉํ๋๋ผ๋, ๋ ๋๋ง ๊ฒฐ๊ณผ๋ง ์๋ฒ์์ ์์ฑ๋ ๋ฟ, ์ดํ์ ๋ชจ๋ ์ธํฐ๋์
์ ํด๋ผ์ด์ธํธ JavaScript์ ์์กดํ์ฃ .
์ด๋ก ์ธํด ๋ค์๊ณผ ๊ฐ์ ํ๊ณ๊ฐ ์์์ด์.
- ๋ฒ๋ค ์ฌ์ด์ฆ ์ฆ๊ฐ: ๋ชจ๋ ์ปดํฌ๋ํธ์ JavaScript ์ฝ๋๊ฐ ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋์ด์ผ ํ์ด์. ํนํ, ์ธํฐ๋์ ์ด ์๋ ์ ์ ์ธ UI๊น์ง๋์.
- ๋ฐ์ดํฐ ํ์นญ์ ๋ณต์ก์ฑ: ํด๋ผ์ด์ธํธ์์ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๊ฑฐ๋, ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๋ ค๋ฉด
getServerSideProps๋getStaticProps๊ฐ์ ํน๋ณํ ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํ์ด์. ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ์ฃ . - ์ด๊ธฐ ๋ก๋ฉ ์ฑ๋ฅ ์ ํ: ํด๋ผ์ด์ธํธ JavaScript ๋ฒ๋ค์ด ๋ค์ด๋ก๋๋๊ณ ์คํ๋๊ธฐ ์ ๊น์ง๋ ์ํธ์์ฉ์ด ๋ถ๊ฐ๋ฅํ์ด์.
App Router๊ฐ ๋์
๋๋ฉด์ Server Components๊ฐ ๊ธฐ๋ณธ๊ฐ์ด๋ผ๋ ์ ์ ๊ฐ๊ณผํ๊ณ , ๊ด์ฑ์ ์ผ๋ก ๋ชจ๋ ์ปดํฌ๋ํธ์ "use client"; ์ง์์ด๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์.
์ด๋ Server Components์ ์ฅ์ ์ ํฌ๊ธฐํ๊ณ ๋ค์ ๊ธฐ์กด์ SPA ๋ฐฉ์์ผ๋ก ๋์๊ฐ๋ ๊ฒ๊ณผ ๋ค๋ฆ์์ด์.
๊ฒฝ๊ณ๋ถํ์ํ๊ฒ
"use client";๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ Server Components์ ํต์ฌ ์ด์ ์ธ ๋ฒ๋ค ํฌ๊ธฐ ๊ฐ์์ ์ด๊ธฐ ๋ก๋ฉ ์๋ ํฅ์์ ์ ํดํ ์ ์์ด์.
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ํญ์ JavaScript ๋ฒ๋ค์ ํฌํจ๋์ด ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋๊ธฐ ๋๋ฌธ์ด์์.
โ๏ธ ํด๊ฒฐ ๋ฐฉ๋ฒ
0๏ธโฃ ํต์ฌ ์์ด๋์ด: Server First ์ ๋ต
Next.js App Router์ ํต์ฌ ์์ด๋์ด๋ "Server First" ์์น์ด์์.
๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ์ปดํฌ๋ํธ๋ Server Component๋ก ๋์ํ๋ฉฐ, ํด๋ผ์ด์ธํธ ์ธก ์ํธ์์ฉ(useState, useEffect, onClick ๋ฑ)์ด ํ์ํ ๊ฒฝ์ฐ์๋ง ๋ช
์์ ์ผ๋ก Client Component๋ก ์ ํํ๋ผ๋ ์๋ฏธ์์.
์ด๊ฒ์ด ๋ฐ๋ก "use client"; ์ง์์ด๊ฐ ํ์ํ ์ด์ ์ฃ .
Server Components (๊ธฐ๋ณธ๊ฐ):
- ์ด๋์ ๋ ๋๋ง๋ ๊น์? ์๋ฒ์์๋ง ๋ ๋๋ง๋ผ์.
- ๋ฌด์์ ํ ์ ์์๊น์? ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ง์ ์ ๊ทผ, ํ์ผ ์์คํ ์ ๊ทผ, API ํค์ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด ์ฌ์ฉ ๋ฑ ์๋ฒ ์ ์ฉ ๋ก์ง์ ์คํํ ์ ์์ด์.
- ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋ ๊น์? JavaScript ๋ฒ๋ค์ ํฌํจ๋์ง ์๊ณ , ๋ ๋๋ง๋ HTML๋ง ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋ผ์. (๋ฐ๋ผ์ ๋ฒ๋ค ์ฌ์ด์ฆ๊ฐ ์ค์ด๋ค์ฃ !)
- ๋ฌด์์ ์ฌ์ฉํ ์ ์์๊น์?
useState,useEffect,onClick๊ณผ ๊ฐ์ React ํ ์ด๋ ๋ธ๋ผ์ฐ์ API(window, document)๋ฅผ ์ง์ ์ฌ์ฉํ ์ ์์ด์. - ์ธ์ ์ฌ์ฉํ ๊น์? ๋ฐ์ดํฐ ํ์นญ, ์ ์ ์ธ UI ๋ ๋๋ง, SEO ์ต์ ํ๊ฐ ํ์ํ ํ์ด์ง, ๋ฐฑ์๋ ๋ก์ง๊ณผ ๋ฐ์ ํ ์ปดํฌ๋ํธ ๋ฑ์ ์ ํฉํด์.
Client Components ("use client";):
- ์ด๋์ ๋ ๋๋ง๋ ๊น์? ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ )์์ ๋ ๋๋ง๋ผ์. (์ด๊ธฐ ๋ ๋๋ง์ ์๋ฒ์์ ์ด๋ฃจ์ด์ง ์ ์์ง๋ง, ์ดํ ํ์ด๋๋ ์ด์ ๋ฐ ์ํธ์์ฉ์ ํด๋ผ์ด์ธํธ์์ ๋ด๋นํด์.)
- ๋ฌด์์ ํ ์ ์์๊น์?
useState,useEffect,useRef,onClick๋ฑ์ React ํ ๊ณผ ์ด๋ฒคํธ ๋ฆฌ์ค๋, ๊ทธ๋ฆฌ๊ณ ๋ธ๋ผ์ฐ์ API์ ์ ๊ทผํ ์ ์์ด์. - ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋ ๊น์? JavaScript ๋ฒ๋ค์ ํฌํจ๋์ด ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋ผ์.
- ๋ฌด์์ ์ฌ์ฉํ ์ ์์๊น์? ์๋ฒ ์ ์ฉ ๋ก์ง(๋ฐ์ดํฐ๋ฒ ์ด์ค ์ง์ ์ ๊ทผ ๋ฑ)์ ์คํํ ์ ์์ด์.
- ์ธ์ ์ฌ์ฉํ ๊น์? ์ํธ์์ฉ์ด ํ์ํ UI (์นด์ดํฐ, ํผ ์ ๋ ฅ, ๋ชจ๋ฌ), ํด๋ผ์ด์ธํธ ์ ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฑ), Context API ์ฌ์ฉ ๋ฑ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ์ง์ ๊ด๋ จ๋ ๋ถ๋ถ์ ์ ํฉํด์.
1๏ธโฃ ์ ์ฉ ๋ฐฉ๋ฒ: ๊ฒฝ๊ณ ๋ช ํํ์ ์ปดํฌ๋ํธ ๋ถ๋ฆฌ
์ฑ๊ณต์ ์ธ Server/Client Component ํ์ฉ์ ์ด ๋์ ๊ฒฝ๊ณ๋ฅผ ๋ช ํํ ํ๊ณ , ์ญํ ์ ์ ์ ํ ๋ถ๋ฆฌํ๋ ๋ฐ ๋ฌ๋ ค์์ด์.
- "Server First" ๋ง์ธ๋์
: ์๋ก์ด ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ๋๋ ํญ์ Server Component๋ก ์์ํ์ธ์. ํด๋ผ์ด์ธํธ ๊ธฐ๋ฅ์ด ํ์ํ๋ค๋ ๋ช
ํํ ์ด์ ๊ฐ ์์ ๋๋ง
"use client";๋ฅผ ์ถ๊ฐํฉ๋๋ค. - ๋ฐ์ดํฐ ํ์นญ์ Server Component์์: ๊ฐ๋ฅํ ํ ๋ฐ์ดํฐ ํ์นญ์ Server Component์์ ์ง์ ์ฒ๋ฆฌํ์ฌ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์์ ๋ฐ์ดํฐ ํ์นญ ๋ก์ง์ ์ ๊ฑฐํ๊ณ , ๋ถํ์ํ API ํธ์ถ ์ค๋ฒํค๋๋ฅผ ์ค์ด์ธ์.
- Client Component๋ 'Leaf' ๋
ธ๋๋ก: ์ํธ์์ฉ์ด ํ์ํ Client Component๋ ๋๋๋ก ํธ๋ฆฌ ๊ตฌ์กฐ์ ๊ฐ์ฅ ํ์(Leaf) ๋
ธ๋์ ๋ฐฐ์นํ์ธ์.
Server Component ์์ Client Component๋ฅผ ๋ ๋๋งํ ์ ์์ง๋ง, Client Component ์์ Server Component๋ฅผ ์ง์ ๋ ๋๋งํ ์๋ ์์ด์.
(Server Component๋ Client Component์ props๋ก ์ ๋ฌ๋ ์ ์์ง๋ง, ์์์ผ๋ก ๋ ๋๋ง๋๋ ๊ฒ์ ์๋์์.) - Props๋ก ๋ฐ์ดํฐ ์ ๋ฌ: Server Component์์ ํ์นญํ ๋ฐ์ดํฐ๋ฅผ Client Component๋ก props๋ฅผ ํตํด ์ ๋ฌํ ์ ์์ด์.
์ด๋ ์ ๋ฌ๋๋ ๋ฐ์ดํฐ๋ ์ง๋ ฌํ ๊ฐ๋ฅํ(serializable) ํํ์ฌ์ผ ํด์.
์ ์ฉํ ํ
"use client";์ง์์ด๋ ํ์ผ์ ๋งจ ์์ ํ ๋ฒ๋ง ์ ์ธํ๋ฉด ํด๋น ํ์ผ ๋ด์ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๋ชจ๋์ด Client Component๋ก ์ฒ๋ฆฌ๋ผ์.
๋ฐ๋ผ์ ์์ ๋จ์์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ Client Component๋ฅผ ๋ง๋ค๊ณ , ์ด๋ฅผ Server Component์์ ๋ถ๋ฌ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ์ ๋ต์ด์์.
๐งช ์์
0๏ธโฃ ์ฝ๋/์ค์ ์์
๋ค์์ Server Components์ Client Components๋ฅผ ํ์ฉํ๋ ์ผ๋ฐ์ ์ธ ํจํด์ด์์.
1. Server Component (๋ฐ์ดํฐ ํ์นญ)
app/dashboard/page.tsx
import { fetchRecentOrders } from '../lib/data'; // ์๋ฒ์์๋ง ์ฌ์ฉ๋ ๋ฐ์ดํฐ ํ์นญ ํจ์ // ์ด ์ปดํฌ๋ํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก Server Component์ ๋๋ค. export default async function DashboardPage() { const orders = await fetchRecentOrders(); // ์๋ฒ์์ ์ง์ ๋ฐ์ดํฐ ํ์นญ // console.log(process.env.DATABASE_URL); // ์๋ฒ ํ๊ฒฝ ๋ณ์ ์ ๊ทผ ๊ฐ๋ฅ return ( <section> <h1>๋์๋ณด๋</h1> <p>์ต๊ทผ ์ฃผ๋ฌธ ๋ชฉ๋ก:</p> <ul> {orders.map((order: any) => ( <li key={order.id}>{order.productName} - {order.amount}์</li> ))} </ul> {/* Client Component๋ฅผ ์์์ผ๋ก ํฌํจํ ์ ์์ด์ */} <InteractiveButton /> </section> ); }
2. Client Component (์ํธ์์ฉ)
app/dashboard/InteractiveButton.tsx
"use client"; // ์ด ํ์ผ์ Client Component์์ ๋ช ์ํฉ๋๋ค. import { useState } from 'react'; export default function InteractiveButton() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> ํด๋ฆญ ํ์: {count} </button> ); }
3. Server Component๊ฐ Client Component์ ๋ฐ์ดํฐ ์ ๋ฌ
app/product/[id]/page.tsx
import { fetchProductDetail } from '@/lib/api'; import AddToCartButton from './AddToCartButton'; // Client Component ์ํฌํธ export default async function ProductDetailPage({ params }: { params: { id: string } }) { const product = await fetchProductDetail(params.id); if (!product) { return <div>์ํ์ ์ฐพ์ ์ ์์ด์.</div>; } return ( <div> <h1>{product.name}</h1> <p>{product.description}</p> <p>๊ฐ๊ฒฉ: {product.price}์</p> {/* Server Component๊ฐ Client Component์ props๋ฅผ ์ ๋ฌํด์ */} <AddToCartButton productId={product.id} productName={product.name} /> </div> ); }
app/product/[id]/AddToCartButton.tsx
"use client"; import { useState } from 'react'; interface AddToCartButtonProps { productId: string; productName: string; } export default function AddToCartButton({ productId, productName }: AddToCartButtonProps) { const [quantity, setQuantity] = useState(1); const handleAddToCart = () => { // ์ฅ๋ฐ๊ตฌ๋ ๋ก์ง (ํด๋ผ์ด์ธํธ์์ ๋์) console.log(`${productName} (ID: ${productId}) ${quantity}๊ฐ๋ฅผ ์ฅ๋ฐ๊ตฌ๋์ ๋ด์์ด์.`); alert(`${productName} ${quantity}๊ฐ๊ฐ ์ฅ๋ฐ๊ตฌ๋์ ์ถ๊ฐ๋์์ด์!`); }; return ( <div> <input type="number" min="1" value={quantity} onChange={(e) => setQuantity(Number(e.target.value))} /> <button onClick={handleAddToCart}>์ฅ๋ฐ๊ตฌ๋์ ์ถ๊ฐ</button> </div> ); }
1๏ธโฃ ์ ์ฉ ๊ฒฐ๊ณผ ๋ฐ ๊ณ ๋ ค์ฌํญ
์ ์์์ฒ๋ผ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ป์ ์ ์์ด์.
- ์ฑ๋ฅ ํฅ์:
DashboardPage์ProductDetailPage๋ Server Component์ด๋ฏ๋ก, ๋ฐ์ดํฐ ํ์นญ ๋ก์ง์ด ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋์ง ์์์.
ํด๋ผ์ด์ธํธ๋ ์ต์ํ์ JavaScript (์ํธ์์ฉ์ด ํ์ํInteractiveButton๊ณผAddToCartButton์ ์ฝ๋๋ง)๋ฅผ ๋ค์ด๋ก๋ํ๊ฒ ๋์ด ์ด๊ธฐ ๋ก๋ฉ ์๋๊ฐ ๋นจ๋ผ์ ธ์. - SEO ์ต์ ํ: ์๋ฒ์์ ๋ ๋๋ง๋ HTML์ด ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋๋ฏ๋ก, ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ ํ์ด์ง ์ฝํ ์ธ ๋ฅผ ์ฝ๊ฒ ํ์ ํ ์ ์์ด์.
- ๋ณด์ ๊ฐํ: ๋ฏผ๊ฐํ API ํค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ ๋ก์ง์ Server Component ๋ด๋ถ์ ์์ ํ๊ฒ ์ ์ง๋ ์ ์์ด์.
- ๊ฐ๋ฐ ๊ฒฝํ:
async/await๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ํ์นญ์ ์ปดํฌ๋ํธ ๋ ๋ฒจ์์ ์ง์ ํ ์ ์์ด, ๊ธฐ์กดgetServerSideProps์ ๊ฐ์ ํน์ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ์ง๊ด์ ์ด์์.
์ ๋ณดServer Component์ Props ์ง๋ ฌํ: Server Component์์ Client Component๋ก ์ ๋ฌํ๋ props๋ ์ง๋ ฌํ ๊ฐ๋ฅํ(serializable) ๊ฐ์ด์ด์ผ ํด์.
ํจ์๋ ์ฌ๋ณผ, ๋ ์ง ๊ฐ์ฒด ๊ฐ์ ์ง๋ ฌํ ๋ถ๊ฐ๋ฅํ ๊ฐ์ Client Component๋ก ์ง์ ์ ๋ฌ๋ ์ ์๋ค๋ ์ ์ ๊ธฐ์ตํ์ธ์.
๐ ์ ๋ฆฌ
0๏ธโฃ ํต์ฌ ์์ฝ
Next.js App Router์์ Server Components์ Client Components๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฑ๋ฅ๊ณผ ๊ตฌ์กฐ๋ฅผ ๊ฒฐ์ ํ๋ ํต์ฌ ์์์์.
- Server Components: ๊ธฐ๋ณธ๊ฐ์ด๋ฉฐ, ์๋ฒ์์ ๋ ๋๋ง๋์ด JavaScript ๋ฒ๋ค์ ํฌํจ๋์ง ์๊ณ , ๋ฐ์ดํฐ ํ์นญ๊ณผ ๋ฐฑ์๋ ๋ก์ง์ ์ ํฉํด์.
- Client Components:
"use client";์ง์์ด๋ฅผ ํตํด ๋ช ์ํ๋ฉฐ, ํด๋ผ์ด์ธํธ์์ ์ํธ์์ฉ(ํ , ์ด๋ฒคํธ ๋ฆฌ์ค๋)์ ์ฒ๋ฆฌํ๊ณ ๋ธ๋ผ์ฐ์ API์ ์ ๊ทผํ ์ ์์ด์.
"Server First" ์์น์ ๋ฐ๋ผ ๊ฐ๋ฅํ ํ Server Component๋ฅผ ํ์ฉํ๊ณ , ์ํธ์์ฉ์ด ํ์ํ ์ต์ํ์ ๋ถ๋ถ์๋ง Client Component๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ์ ๋ต์ด์์. ์ด๋ ๋ฒ๋ค ์ฌ์ด์ฆ ๊ฐ์, ์ด๊ธฐ ๋ก๋ฉ ์๋ ํฅ์, SEO ์ต์ ํ, ๊ทธ๋ฆฌ๊ณ ๋ณด์ ๊ฐํ๋ก ์ด์ด์ ธ์.
1๏ธโฃ ๋ค์ ์ก์
์ค๋ ๋ฐฐ์ด ๋ด์ฉ์ ๋ฐํ์ผ๋ก ๊ธฐ์กด Next.js ํ๋ก์ ํธ์ ์ปดํฌ๋ํธ๋ค์ Server Component์ Client Component๋ก ์ด๋ป๊ฒ ๋ถ๋ฆฌํ ์ ์์์ง ๊ณ ๋ฏผํด๋ณด์ธ์.
์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ํ๋ค๋ฉด, Server First ๋ง์ธ๋์
์ผ๋ก ์ปดํฌ๋ํธ๋ฅผ ์ค๊ณํ๊ณ , ๋ถํ์ํ "use client"; ์ฌ์ฉ์ ์ง์ํ๋ฉฐ ์ต์ ํ๋ Next.js ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํด๋ณด์๊ธธ ๊ถํด๋๋ ค์.
๋ ๊น์ด ์๋ ์ดํด๋ฅผ ์ํด Next.js ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ค์ํ ์์์ ํจํด๋ค์ ํ์ํ๋ ๊ฒ๋ ์์ฃผ ์ข์ ๋ฐฉ๋ฒ์ด์์.
๐ฎ ์ฐธ๊ณ
- Next.js ๊ณต์ ๋ฌธ์: Server Components
- Next.js ๊ณต์ ๋ฌธ์: Client Components
- React ๊ณต์ ๋ฌธ์: Server Components
์ฐ๊ด๋ ํฌ์คํธ
๋จ์ด: 1,844๊ฐ20๋ถ[๐ค] Next.js App Router: Server Components์ Client Components, ์๋ฒฝ ์ ๋ณตํด์!
Next.js 13+ App Router์์ Server Components์ Client Components๊ฐ ์ด๋ป๊ฒ ๋์ํ๊ณ , ์ธ์ ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง ๋ช ํํ ์ดํดํ์ฌ ์ฑ๋ฅ ์ต์ ํ์ ํจ์จ์ ์ธ ๊ฐ๋ฐ์ ์ด๋ฃจ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์์๋ด์.