Ch.16 Next.js 입문 — 풀스택 React 프레임워크

서버 vs 클라이언트 컴포넌트

서버 컴포넌트와 클라이언트 컴포넌트의 차이를 이해한다'use client' 지시어의 의미를 설명할 수 있다서버에서 데이터, 클라이언트에서 인터랙션 패턴을 적용할 수 있다

'use client' 붙이면 뭐가 달라지는데?

Next.js 프로젝트에서 useState를 썼더니 에러가 납니다. 'use client'를 붙이면 해결되는데... 왜?

서버 컴포넌트와 클라이언트 컴포넌트, 언제 뭘 써야 할까?

서버 컴포넌트 = 데이터, 클라이언트 컴포넌트 = 인터랙션. 역할을 나누면 빠르고 안전합니다.


article

핵심 내용

Next.js의 모든 컴포넌트는 기본적으로 서버 컴포넌트입니다

// 서버 컴포넌트 — 별도 표시 없음 (기본값)
// app/users/page.tsx

export default async function UsersPage() {
  // ✅ 서버에서 직접 DB 조회!
  const users = await db.user.findMany();

  // ✅ 서버에서 직접 API 호출!
  const data = await fetch("https://api.example.com/data");

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

// ❌ useState, useEffect 사용 불가!
// ❌ onClick 등 이벤트 핸들러 불가!

'use client' 한 줄이면 브라우저에서 실행되는 컴포넌트로 전환됩니다

"use client"; // ← 이 한 줄이 핵심!

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        +1
      </button>
    </div>
  );
}

서버에서 데이터를 가져오고 클라이언트에서 인터랙션을 처리합니다

// 1️⃣ 클라이언트 컴포넌트 — 좋아요 버튼
// components/LikeButton.tsx
"use client";
import { useState } from "react";

export function LikeButton({ initialLikes }: {
  initialLikes: number;
}) {
  const [likes, setLikes] = useState(initialLikes);
  return (
    <button onClick={() => setLikes(likes + 1)}>
      ❤️ {likes}
    </button>
  );
}
// 2️⃣ 서버 컴포넌트 — 게시글 페이지
// app/post/[id]/page.tsx
import { LikeButton } from "@/components/LikeButton";

export default async function PostPage({
  params,
}: {
  params: { id: string };
}) {
  // ✅ 서버에서 DB 조회
  const post = await db.post.findUnique({
    where: { id: Number(params.id) },
  });

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      {/* ✅ 클라이언트 컴포넌트에 데이터 전달 */}
      <LikeButton initialLikes={post.likes} />
    </article>
  );
}

서버 컴포넌트: DB에서 게시글 데이터 조회

HTML 생성: 서버에서 완성된 HTML 렌더링

클라이언트 컴포넌트: LikeButton만 브라우저에서 활성화

인터랙션: 좋아요 버튼 클릭 가능!

바이브 코더 원칙 기본은 서버 컴포넌트로 두고, useState, onClick이 필요한 부분만 'use client'를 붙이세요. 최소한의 클라이언트 컴포넌트가 최적의 성능을 만듭니다.

Next.js에서 컴포넌트의 기본값은?

서버 컴포넌트에서 useState를 사용할 수 있다.

서버 컴포넌트 안에서 클라이언트 컴포넌트를 사용하려면?

'use client'를 최대한 많이 사용하는 것이 좋다.

key

핵심 용어

JS 번들 없음

서버에서 실행되므로 브라우저에 JS를 보내지 않음 — 빠름!

🗄️

직접 DB 접근

API 없이 서버에서 바로 데이터베이스 조회 가능

🔒

보안

API 키, DB 비밀번호가 클라이언트에 노출 안 됨

compare_arrows

비교 정리

항목서버 컴포넌트클라이언트 컴포넌트
async/await✅ 가능❌ 불가
useState/useEffect❌ 불가✅ 가능
onClick 등 이벤트❌ 불가✅ 가능
DB/파일 직접 접근✅ 가능❌ 불가
edit_note

정리 노트

서버 vs 클라이언트 컴포넌트 비교

핵심 개념

서버 컴포넌트
Next.js의 기본값 — 서버에서 렌더링, JS 번들 없음
클라이언트 컴포넌트
'use client' 선언 — useState, onClick 등 인터랙션 처리
최소 클라이언트 원칙
인터랙션이 필요한 최소 단위에만 'use client' 사용
서버+클라이언트 조합
서버 컴포넌트 안에 클라이언트 컴포넌트를 자식으로 배치

'use client'는 최소한으로 — JS 번들이 작을수록 성능이 좋습니다.

image

시각 자료

퀴즈와 인터랙션으로 더 깊이 학습하세요

play_circle인터랙티브 레슨 시작