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 프로젝트 구성이 가능합니다.

Next.js 프로젝트에서 다음과 같은 오류를 만나는 경우가 있습니다:

Module not found: Can't resolve 'lucide-react'

이 오류는 외부 패키지인 lucide-react가 프로젝트에 설치되지 않았을 때 발생합니다. 이 글에서는 오류의 원인과 해결 방법을 간단하게 정리해보겠습니다.


1. 오류 원인

lucide-react는 아이콘 컴포넌트를 제공하는 라이브러리로, 보통 shadcn/ui 기반의 UI 컴포넌트를 생성할 때 함께 사용됩니다. 예를 들어 select, button, input 등 컴포넌트 내에서 다음과 같이 아이콘을 import할 수 있습니다:

import { CheckIcon, ChevronDownIcon } from "lucide-react";

하지만 lucide-react 패키지가 설치되어 있지 않으면, Next.js는 해당 모듈을 찾을 수 없다는 에러를 출력하게 됩니다.


2. lucide-react란?

lucide-react는 Feather Icons를 기반으로 만든 React용 오픈소스 아이콘 라이브러리입니다. SVG 아이콘을 컴포넌트 형태로 제공하며, 다음과 같은 특징을 가집니다:

  • React 컴포넌트로 손쉽게 아이콘 사용 가능
  • Feather 스타일의 미니멀하고 직관적인 디자인
  • shadcn/ui에서 기본 아이콘 세트로 자주 사용됨
  • 필요에 따라 개별 아이콘만 import하여 번들 크기 최적화 가능

사용 예시:

import { CheckIcon, TrashIcon } from 'lucide-react';

function Example() {
  return <CheckIcon size={24} className="text-green-500" />;
}

공식 GitHub: https://github.com/lucide-icons/lucide


3. 해결 방법

아래 명령어를 실행하여 lucide-react 패키지를 설치하면 문제가 해결됩니다.

npm install lucide-react

또는 yarn을 사용하는 경우:

yarn add lucide-react

설치가 완료되면 개발 서버를 재시작하세요:

npm run dev

4. 추가 팁: Shadcn UI 사용자라면

shadcn/ui를 이용해 컴포넌트를 생성한 경우, 필요한 의존성(lucide-react, tailwind-variants 등)이 자동으로 설치되지 않는 경우도 있습니다. 따라서 컴포넌트 생성 후 README.md 또는 CLI 안내에 따라 필요한 의존성은 수동으로 설치해야 합니다.

Next.js로 프로젝트를 개발하다 보면 아래와 같은 오류를 만날 수 있습니다:

Module not found: Can't resolve '@/components/ui/tabs'

이 오류는 프로젝트가 @/components/ui/tabs 경로에 해당하는 파일이나 모듈을 찾을 수 없을 때 발생합니다. 이번 글에서는 이 문제를 해결하는 방법을 단계적으로 정리해보겠습니다.


1. 경로에 파일이 실제로 존재하는지 확인

가장 먼저 확인할 것은 tabs.tsx 파일이 실제로 존재하는지 여부입니다.

경로 예시:

src/
└── components/
    └── ui/
        └── tabs.tsx

혹은 tabs/index.tsx 형식으로 되어 있을 수도 있습니다. 파일이 존재하지 않으면 직접 생성하거나, 다음 단계로 넘어가세요.


2. @ alias가 작동하도록 설정되었는지 확인 (tsconfig.json)

@를 사용하는 경우, 해당 경로를 tsconfig.json 또는 jsconfig.json에서 설정해야 합니다.

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

이 설정이 없다면 @/components/...는 정상적으로 인식되지 않습니다. 설정을 저장한 후, 에디터와 서버를 재시작해야 적용됩니다.


3. Shadcn UI를 사용하는 경우

shadcn/ui 컴포넌트 라이브러리를 사용하는 프로젝트라면, 해당 컴포넌트를 명령어로 추가해야 합니다.

npx shadcn-ui@latest add tabs

위 명령어를 실행하면 components/ui/tabs.tsx가 생성되어 오류가 해결됩니다.


4. 캐시 삭제 후 재빌드

가끔 Next.js의 캐시로 인해 오류가 지속되는 경우가 있습니다. 다음 명령어로 .next 캐시 폴더를 삭제하고 다시 실행해보세요.

rm -rf .next
npm run dev

5. 기타 체크리스트

  • Git에 누락된 파일이 있는지 확인
  • 파일명이 대소문자를 정확히 구분하는지 확인 (Tabs.tsx vs tabs.tsx)
  • ESLint, TypeScript 에러가 있는지 확인

+ Recent posts