Next.js 13 이상부터 도입된 app 디렉토리 기반 구조는 서버 컴포넌트(Server Component)를 기본으로 채택합니다. 이로 인해 클라이언트 전용 기능인 useState, useEffect, onClick 등을 사용할 경우, 아래와 같은 오류가 발생할 수 있습니다.
에러 메시지 예시
Error: You're importing a component that needs `useState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the "use client" directive.
원인 설명
Next.js의 app 디렉토리에서는 페이지나 컴포넌트 파일이 기본적으로 서버 컴포넌트로 처리됩니다. 서버 컴포넌트는 브라우저 상호작용이 필요 없는 정적/비동기 작업에 적합하지만, useState처럼 브라우저에서만 동작해야 하는 React Hook은 클라이언트 컴포넌트에서만 사용 가능합니다.
해결 방법: "use client" 지시어 추가
해당 컴포넌트 파일 최상단에 다음 줄을 추가하면 해결됩니다:
"use client";
예시 코드
"use client";
import { useState } from "react";
import { Input } from "@/components/ui/input";
export default function SignUpPage() {
const [agree, setAgree] = useState(false);
return (
<div>
<Input type="checkbox" checked={agree} onChange={() => setAgree(!agree)} />
<label>동의합니다</label>
</div>
);
}
언제 "use client"를 붙여야 할까?
다음과 같은 경우, 해당 파일(혹은 그 상위 레벨 컴포넌트)은 클라이언트 컴포넌트여야 하므로 "use client"를 선언해야 합니다:
- useState, useEffect, useRef 등 React 훅을 사용하는 경우
- onClick, onChange 등 이벤트 핸들러를 사용하는 경우
- 브라우저 전용 API(window, localStorage 등)를 사용하는 경우
참고 사항
- "use client"는 해당 파일에만 적용됩니다. 하위 컴포넌트에는 자동으로 전파되지 않습니다.
- 가능하면 클라이언트 기능은 최소한의 파일에서만 분리해 사용하는 것이 SSR 최적화에 유리합니다.
정리
Next.js의 서버 중심 아키텍처는 성능과 최적화에 강점이 있지만, 사용자 인터랙션을 구현하려면 클라이언트 컴포넌트가 필요합니다. "use client" 지시어는 이를 선언하는 방식이며, 이 구조를 이해하면 더욱 효율적인 Next.js 프로젝트 구성이 가능합니다.
'Front-End > 트러블슈팅' 카테고리의 다른 글
Next.js에서 'lucide-react' 모듈을 찾을 수 없는 오류 해결 방법 (0) | 2025.05.07 |
---|---|
Next.js 프로젝트에서 '@/components/ui/tabs' 모듈을 찾을 수 없는 오류 해결 방법 (0) | 2025.05.07 |