useState를 썼는데 왜 에러가 날까? (Ecmascript file had an error)

Hwnsng·2026년 1월 14일

Next.js

목록 보기
2/3
post-thumbnail

💡 문제 상황

Next.js App Router 환경에서 아래와 같은 에러가 발생했다.

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.

에러가 발생한 코드는 다음과 같았다.

import { useState } from "react";

export default function Nav() {
  const [active, setActive] = useState("10대");
  return <div>Nav</div>;
}

단순히 useState를 사용했을 뿐인데, 빌드 에러가 발생했다.

❓ 에러 원인

이 문제의 핵심은 Next.js App Router기본 동작 방식 때문이다.

App Router의 기본 규칙

App Router에서 작성하는 컴포넌트는 기본적으로 Server Component이다.

Server Component서버에서만 실행되고, 따라서 아래 기능들을 사용할 수 없다

  1. useState, useEffect
  2. onClick, onChange 등등의 이벤트 핸들러
  3. 브라우저 API (window, document 등)

즉, useState는 브라우저에서만 동작하는 React Hook인데 Server Component에서 사용했기 때문에 에러가 발생한 것이다.

⚙️ Server Component vs Client Component

아래는 Server Component와 Client Component를 비교하는 표이다.

구분Server ComponentClient Component
기본 여부기본값명시 필요
useState
이벤트 처리
렌더링 위치서버브라우저

그래서 상태나 이벤트가 필요한 컴포넌트반드시 Client Component여야 한다.

🔥 해결 방법

해결 방법은 아주 간단한데 그냥 파일 최상단"use client"를 추가해주면 된다.

"use client";

import { useState } from "react";

export default function Nav() {
  const [active, setActive] = useState("10대");
  return <div>Nav</div>;
}

중요한 점은 반드시 파일 최상단, import보다 위에 있어야 한다는 것이다.

🤮 잘못된 예시

import { useState } from "react";
"use client";

이렇게 작성하면 인식되지 않는다.

❓ 왜 꼭 최상단이어야 할까

Next.js는 파일을 읽을 때 맨 처음에 "use client"가 있는지 보고 이 파일을 Client Component로 변환할지 결정한다.

즉, "use client"는 일반 문자열이 아니라 Next.js에게 주는 컴파일 지시자이다.

그래서 import 이후에 작성하면 이미 Server Component로 판단된 뒤라 의미가 없어지는 것이다.

📄 Tip

Nav.tsx에 "use client"가 있으면 그 아래에서 import되는 컴포넌트들은 자동으로 Client Component가 된다. 그러므로 하위 컴포넌트에 "use client"를 중복해서 쓸 필요는 없다

profile
Frontend Developer

0개의 댓글