TIL

'use client'는 CSR 스위치가 아니에요

· 2026-10-07

오늘 배운 것 한 줄

Next.js App Router에서는 컴포넌트가 기본으로 서버에서 돌아요. 그리고 ’use client’는 브라우저에서 그리라는 스위치가 아니라, 여기서부터 브라우저로 보낼 코드라는 경계 표시다.

왜 중요한가

처음엔 이름만 보고 CSR로 바꾸는 지시어인 줄 알았어요. 그런데 ’use client’를 붙인 컴포넌트도 첫 HTML은 서버가 만들어요. 브라우저는 그 HTML 위에 클릭 같은 기능을 붙이고요(hydration). 달라지는 건 그 파일의 JavaScript가 브라우저로 내려간다는 점이에요.

그래서 붙이는 위치가 중요해요. 이 경계는 아래로 번지거든요. ‘use client’ 파일이 불러오는 컴포넌트도 전부 브라우저 몫이 돼요. 페이지 맨 위에 붙이면 보여 주기만 하는 부분까지 다 내려가요.

어제 배운 이벤트 위임은 이벤트를 어디서 들을지의 문제였어요. 오늘은 이벤트가 어디서 돌 수 있는지의 문제였고요. 서버에는 클릭이 없으니까요.

내 예시

TIL 카드에 북마크 버튼을 단다고 해 볼게요.

// BookmarkButton.tsx — 클릭이 있는 가장 작은 단위에만
'use client'; // import보다 위, 파일 첫 줄
import { useState } from 'react';

export default function BookmarkButton() {
  const [saved, setSaved] = useState(false);
  return (
    <button aria-pressed={saved} onClick={() => setSaved(!saved)}>
      {saved ? '저장됨' : '나중에 읽기'}
    </button>
  );
}
// TilCard.tsx — 지시어 없음. 서버 컴포넌트로 남는다
import BookmarkButton from './BookmarkButton';

export default function TilCard({ title }: { title: string }) {
  return (
    <article>
      <h3>{title}</h3>
      <BookmarkButton />
    </article>
  );
}

카드는 서버에 두고 버튼만 브라우저로 보내요. 제목처럼 보여 주기만 하는 부분은 컴포넌트 코드 없이 HTML로만 도착해요.

다음에 해 볼 것

’use client’를 일부러 빼고 onClick을 써서 실제 에러 메시지를 직접 확인해 볼 거예요. 그리고 클라이언트 컴포넌트 안에 서버 컴포넌트를 children으로 넣는 패턴도 손으로 해 볼게요.

주제

Next.jsReact서버 컴포넌트

배운 개념

'use client' 경계 — 기본은 서버 컴포넌트다 · Prerender 와 Hydration — 뼈대를 먼저 보내고 기능을 붓는다

앤디의 마케팅노트

마케팅을 시스템으로 만드는 과정을 매주 기록해요. 잘 된 것도, 안 된 것도 같이 봐요.

maily에서 구독하기