Next.js/기초/Lesson 02
Client vs Server 경계 — 'use client' 가 모든 걸 바꾼다
35분·theory
이 챕터
2/3
TypeScript
Client vs Server 경계 — 'use client' 가 모든 걸 바꾼다
💡 왜 배워야 할까요? — Server/Client 경계가 곧 번들 크기와 보안의 경계
🎯
App Router 의 모든 컴포넌트는 기본 Server. 'use client' 를 어디 붙이느냐가 클라이언트 번들 크기를 결정합니다.
💼
Client 안에서 DB·시크릿·`fs` 모듈을 import 하면 빌드 에러 — 경계를 잘 못 그리면 서비스가 빌드조차 안 됩니다.
⚡
반대로 모든 걸 'use client' 로 만들면 Server Component 의 장점(0KB 번들, 직접 DB 접근) 을 다 잃습니다 — 그건 그냥 옛 SPA.
🔗
가장 중요한 패턴: **Server 가 Client 를 children 으로 끼우는 composition** — 이게 안 되면 Client 안에서 Server 데이터를 못 씁니다.
🏢 실무에서는
실무에서 가장 흔한 실수: 페이지 컴포넌트 맨 위에 무심코 'use client' 를 적고 그 안에서 `await db.user.findMany()` 호출 → 브라우저에서 DB 가 안 부르니 빌드 에러. 해결책은 'use client' 를 정말 상호작용이 필요한 작은 leaf 컴포넌트(버튼·폼·useState 가 있는 부분) 에만 두고, 나머지는 Server 로 두는 것.
경계의 3가지 핵심 규칙
1. 'use client' 의 진짜 의미
- ▸이 파일과 이 파일이 import 하는 모든 컴포넌트 가 Client Component 가 됩니다 (전염성).
- ▸즉, 'use client' 는 "이 컴포넌트만" 이 아니라 "여기서부터 시작하는 트리" 의 경계 표시.
- ▸한 페이지 안에서 'use client' 경계는 여러 개 있을 수 있고, 그게 자연스럽습니다.
2. 'use client' 가 필요한 5가지 신호
이 중 하나라도 필요 → 'use client'. 없으면 Server.
3. Server → Client 는 OK, Client → Server 는 ❌
4. 해결책 — children prop 으로 composition
핵심: Client 가 Server 를 "import" 해서 직접 끼우는 건 안 되지만, Server 가 만든 JSX 를 Client 의 children prop 으로 "넘겨주는" 건 OK. 이게 App Router 의 가장 중요한 패턴.
5. Server Component 안에서 자주 헷갈리는 것
💡 💡 경계 잘 그리는 5가지 규칙
1. 'use client' 는 가능한 leaf 에 가깝게
페이지·레이아웃 같은 큰 컴포넌트에 'use client' 박는 건 거의 잘못된 결정. 진짜 상호작용이 필요한 작은 컴포넌트(버튼·인풋·드롭다운)에만.
2. 'use client' 의 전염성 기억하기
'use client' 가 붙은 파일이 import 하는 모든 것은 Client. Server Component 라도 그 import 트리 안에 들어가면 Client 처리됨.
3. Client 안에서 Server 콘텐츠가 필요하면 children 으로 받기
4. Server 에 onClick 못 박는다 — Client leaf 로 추출
빌드 에러로 알려주긴 하지만, 처음부터 패턴 알고 짜는 게 빠름.
5. 'use client' 를 붙여도 hydration 후 그 컴포넌트는 여전히 서버에서도 렌더됨
초기 HTML 은 서버가 그리고, 브라우저에서 hydration 으로 살아남. 즉 SSR 은 항상 일어남. 'use client' = '브라우저 전용 실행' 이 아니라 '브라우저에서도 살아남' 의 표시.
⚡ 직접 실행해보기 — 경계 위반 검사 시뮬레이션
각 컴포넌트가 어떤 환경에서 동작 가능한지 시뮬레이션합니다.
✏️ JS 코드
📟 콘솔 출력
▶ 실행 버튼을 눌러보세요
⚠️ 브라우저 샌드박스에서 실행 — console.log()만 지원, alert/fetch 불가
확인 퀴즈
다음 중 Server Component 에서 그대로 사용 가능한 것은? (Client Component 로 추출이 필요하지 않은 것)
먼저 읽으면 좋은 개념: App Router 기초 — Pages Router 와의 차이