01 · Concept

React Server Components

서버에서 렌더링되어 클라이언트 번들을 줄이는 새로운 컴포넌트 패러다임입니다.

RSC는 서버에서만 실행되는 컴포넌트로, DB 접근과 파일시스템 사용이 가능하지만 useState나 이벤트 핸들러는 사용할 수 없습니다. "use client"로 Client Component를 선언하고, "use server"로 Server Actions를 정의합니다. Next.js App Router에서 기본값은 Server Component입니다.

02 · Interactive Demo

Server / Client Component 렌더링 흐름

각 컴포넌트 유형의 렌더링 과정과 번들 사이즈 차이를 확인하세요.

// Server Component (기본값 — "use client" 없음)
async function UserList() {
  const users = await db.user.findMany(); // 직접 DB 접근

  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}
Render Flow
1. 서버 실행
서버에서 컴포넌트 렌더링 + 데이터 fetch
2. RSC Payload
직렬화된 React 트리를 클라이언트로 전송
3. HTML 스트리밍
브라우저에 HTML 스트리밍 렌더
4. No Hydration
JS 번들 없음 — hydration 불필요
Bundle:
0 KB (JS 번들에 포함되지 않음)
03 · Code Example

코드 예시

실제 코드로 동작 원리를 확인하세요.

// app/users/page.tsx — Server Component (기본값)
// "use client" 없으면 자동으로 Server Component

import { db } from '@/lib/db';

async function UsersPage() {
  // 서버에서 직접 DB 접근 — API 라우트 불필요
  const users = await db.user.findMany({
    orderBy: { createdAt: 'desc' },
  });

  return (
    <main>
      <h1>사용자 목록</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            {user.name} — {user.email}
          </li>
        ))}
      </ul>
    </main>
  );
}

export default UsersPage;

// 이 컴포넌트의 JS는 클라이언트 번들에 포함되지 않음
// → 번들 사이즈 0KB, SEO 최적화
04 · Interview Point

면접 핵심 질문

RSC는 서버에서만 실행되는 React 컴포넌트입니다. async/await로 데이터를 직접 fetch하고, DB에 접근할 수 있지만 useState, useEffect 등 클라이언트 훅은 사용할 수 없습니다. 컴포넌트 코드가 클라이언트 번들에 포함되지 않아 번들 사이즈를 줄이고, 서버의 리소스(DB, 파일시스템)에 직접 접근할 수 있습니다.
"use client"를 파일 최상단에 선언하면 해당 파일과 그 하위 import가 Client Component가 됩니다. 이것이 Server/Client의 경계(boundary)입니다. Server Component는 Client Component를 자식으로 가질 수 있지만, Client Component 안에서 Server Component를 직접 import할 수 없습니다(children prop으로 전달은 가능). "use server"는 Server Actions를 정의하며, 클라이언트에서 호출 가능한 서버 함수를 만듭니다.
장점: 1) 번들 사이즈 감소 — 서버 코드가 클라이언트로 전송되지 않음 2) 서버 리소스 직접 접근 — API 라우트 없이 DB, 파일시스템 사용 3) 자동 코드 분할 — Client Component만 필요할 때 로드 4) 스트리밍 렌더링 — Suspense와 연동하여 점진적 로딩

단점: 1) 인터랙션 불가 — useState, 이벤트 핸들러 사용 불가 2) 학습 곡선 — Server/Client 경계 이해 필요 3) 직렬화 제한 — props로 함수, 클래스 인스턴스 등 전달 불가