Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 중복된 단어
- 문자열순서바꾸기
- ubuntu타임존
- 깃 토큰 만료
- 중첩배열
- 중첩배열평탄화
- 코딩 어?
- 우분투 시간 변경
- js 문자열을 문자배열로
- 재귀스왑
- lastIndexOf()
- 단어 제거
- 객체의 밸류값만 찾기
- ...점점점문법
- 레디스 확인
- 중복단어제거
- 배엘에서 스왑
- 제로베이스
- 중복 문자열
- 시퀄 문법
- indexOf()
- 중복문자제거
- 스프링 데이타 JPA
- 프론트엔드 스쿨
- 5.3.8 Modifying Queries
- 객체의키값만 찾기
- 아래로펼치기
- sql 문자열 패턴 검색
- @Moditying @Query
- 문자열 중복
Archives
- Today
- Total
코딩기록
문법) 'use client'를 작성하는 이유- 서버 컴포넌트, 클라이언트 컴포넌트 본문
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>;
}
참고
쳇지피티
반응형
'프론트 > 리액트' 카테고리의 다른 글
Next.js) 폴더명에 []대괄호 사용- 동적라우팅 (1) | 2025.06.20 |
---|---|
Carousel) Swiper(스와이퍼)- 반응형 슬라이드(캐러셀) 라이브러리 (0) | 2025.06.18 |
반복되는 JSX 문법 .map으로 간략하게 (0) | 2025.06.10 |
css) input 포커스 시 움직임 수정 (0) | 2025.06.09 |
트러블슈팅 ) transition 적용 (2) | 2025.06.04 |
Comments