코딩기록

문법) 'use client'를 작성하는 이유- 서버 컴포넌트, 클라이언트 컴포넌트 본문

프론트/리액트

문법) 'use client'를 작성하는 이유- 서버 컴포넌트, 클라이언트 컴포넌트

뽀짝코딩 2025. 6. 11. 12:24
728x90

 


'use client'는 Next.js App Router에서 클라이언트 컴포넌트임을 명시하는 지시문.


✅ 'use client'를 작성하는 이유

📌 1. 기본은 서버 컴포넌트이기 때문

Next.js(App Router 기준)에서는 .tsx 파일은 기본적으로 서버 컴포넌트이다.
→ 서버에서 실행되고, HTML을 생성해서 클라이언트에 전달한다.

하지만:

  • 상태(useState)
  • 이펙트(useEffect)
  • 이벤트 핸들러 (onClick, onChange)
  • 브라우저 API (localStorage, window 등)

이런 브라우저 전용 기능을 쓰려면 클라이언트 컴포넌트여야 한다.


📌 2. 'use client'가 필요할 때

아래 조건에 해당하면 컴포넌트 맨 위에 'use client'를 써야 한다

조건 예시

useState, useEffect, useRef 사용 시 ✅ 리액트 훅 사용
onClick, onSubmit 등 이벤트 핸들러 사용 시 ✅ 버튼 클릭 처리 등
브라우저 API 사용 시 ✅ window, localStorage 등
상위 컴포넌트가 서버 컴포넌트인데, 이 컴포넌트는 클라이언트 기능을 써야 할 때 ✅ props는 못 받더라도 내부에서 클라이언트 동작 필요할 때

✅**“상위 컴포넌트가 서버 컴포넌트이고, 프롭스로 값을 넘겨주지 않으면 ‘클라이언트로 따로 분리해서 써야 한다’”**

'use client'는 상위에서 props를 받지 않더라도, 내부에서 클라이언트 기능을 쓰면 반드시 필요!!


✅ 예시

❌ 아래는 오류남 (클릭 이벤트는 클라이언트에서만 동작하므로)

// app/some/page.tsx

export default function SomePage() {
  return (
    <button onClick={() => alert('hello')}>클릭</button>
  );
}
  • onClick 사용했는데 'use client'가 없어서 오류가 난다.

✅ 고치려면 이렇게:

'use client';

export default function SomePage() {
  return (
    <button onClick={() => alert('hello')}>클릭</button>
  );
}


 'use client'가 상위 컴포넌트로 자동 전파되지 않는 이유
서버/클라이언트 컴포넌트 혼합 전략까지 간단히 정리 📘


✅ 'use client'는 왜 자동으로 상위에 전파되지 않나요?

👉 명확한 분리와 번들 크기 최소화를 위해서.

예시:

// ClientButton.tsx
'use client';
export default function ClientButton() {
  return <button onClick={() => alert('hi')}>버튼</button>;
}
// ServerPage.tsx
export default function ServerPage() {
  return <ClientButton />;
}
  • 여기서 ServerPage는 서버 컴포넌트이고,
  • ClientButton은 클라이언트 컴포넌트이다.
  • 이 구조는 허용.

✅ 즉, 서버 컴포넌트가 클라이언트 컴포넌트를 자식으로 포함하는 것은 가능하지만,
그 반대는 불가능.


❌ 반대는 안 됨

// 'use client' 있음
'use client';
import ServerComponent from './ServerComponent';

export default function ClientPage() {
  return <ServerComponent />; // ❌ 에러 발생 가능
}

클라이언트 컴포넌트에서 서버 컴포넌트를 직접 임포트하면 안 된다.
서버 컴포넌트는 Node.js 환경에서만 실행되므로, 브라우저에서 사용할 수 없기 때문.


✅ 서버/클라이언트 혼합 전략

목적 전략

초기 페이지 로딩 속도 최적화 최대한 서버 컴포넌트로 유지 (HTML 먼저 렌더링)
클릭, 입력 등 인터랙션 필요 해당 부분만 클라이언트 컴포넌트로 분리 ('use client')
클라이언트 전용 기능이 많음 전체 컴포넌트를 'use client' 처리하되, 서버 컴포넌트는 fetch로 데이터 전달
UI 분리 필요할 때 components/ClientPart.tsx, components/ServerPart.tsx 식으로 나누기

💡 팁: 서버 컴포넌트 → 클라이언트 컴포넌트 프롭스로 데이터 넘기기

// ServerComponent.tsx
import ClientComponent from './ClientComponent';

export default async function ServerComponent() {
  const data = await fetch(...).then(res => res.json());
  return <ClientComponent data={data} />;
}
// ClientComponent.tsx
'use client';

export default function ClientComponent({ data }: { data: any }) {
  return <div>{data.title}</div>;
}

 

 

 

 

 

 

참고 

쳇지피티

 

 

 

 

 

 

반응형
Comments