공식문서 스터디 중 정리
공식문서 코드 일부
"use client";
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from "@heroicons/react/24/outline";
import Link from "next/link";
import { usePathname } from "next/navigation";
import clsx from "clsx";
// Map of links to display in the side navigation.
// Depending on the size of the application, this would be stored in a database.
const links = [
{ name: "Home", href: "/dashboard", icon: HomeIcon },
{
name: "Invoices",
href: "/dashboard/invoices",
icon: DocumentDuplicateIcon,
},
{ name: "Customers", href: "/dashboard/customers", icon: UserGroupIcon },
];
export default function NavLinks() {
const pathname = usePathname();
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className={clsx(
"flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3",
{
"bg-sky-100 text-blue-600": pathname === link.href,
}
)}
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
"use client";
의 역할Next.js에서
"use client";
라는 지시는 클라이언트 컴포넌트(Client Component)로 지정하는 역할을 합니다. 이 구문을 파일 맨 위에 추가하면, 해당 파일이 클라이언트 측에서만 실행되는 컴포넌트임을 명시하게 된다.
Next.js 13에서는 서버 컴포넌트(Server Components)와 클라이언트 컴포넌트(Client Components)를 구분하는 개념이 도입되었다. 기본적으로, Next.js는 컴포넌트를 서버에서 렌더링하는 서버 컴포넌트로 간주한다. 하지만, 클라이언트에서만 동작해야 하는 로직(예: 이벤트 핸들러, 상태 관리, 브라우저 API 사용 등)을 포함한 컴포넌트는 클라이언트 컴포넌트로 선언해야 한다.
"use client";
의 필요성
usePathname
훅 사용:usePathname
훅은 클라이언트에서만 실행되는 브라우저 관련 API를 사용하여 현재 경로(pathname)를 가져온다. 이 훅은 서버에서 실행할 수 없기 때문에, 이 파일은 클라이언트에서만 실행되어야 한다.- 브라우저 이벤트 처리: 이 컴포넌트는 사용자와의 상호작용(예: 클릭 이벤트 처리)을 포함하므로, 클라이언트 측에서 렌더링되어야 한다.
import
를 안 했는데 가능한 이유
"use client";
는 Next.js의 특정 구문으로, 일반적인 JavaScript의import
와는 다른 역할을 한다. 따라서import
문처럼 별도의 모듈을 가져오는 것이 아니라, 해당 컴포넌트가 클라이언트 측에서만 동작하도록 Next.js에 지시하는 특별한 구문이다.import
는 파일 간의 코드 공유를 위해 필요한 구문이지만,"use client";
는 이 파일이 클라이언트 컴포넌트임을 지정하는 데만 사용된다.
"use client";
는 Next.js에서 해당 컴포넌트가 클라이언트 측에서만 실행되도록 지정하는 구문.- 클라이언트에서만 실행 가능한 훅(예:
usePathname
)을 사용할 때, 이 지시문이 필요.- 이는
import
와는 다른 역할을 하며, 컴포넌트를 클라이언트에서만 렌더링하도록 지정.
"use client";
를 이 코드에서 제거하면?"use client";
를 제거했을 때 발생하는 문제
usePathname
훅이 동작하지 않음
usePathname
훅은 클라이언트 측에서만 사용할 수 있는 훅이다. 이 훅은 브라우저에서 현재 URL 경로를 가져오는 역할을 한다."use client";
가 없으면, 이 파일은 기본적으로 서버 컴포넌트로 간주되기 때문에, 서버에서는usePathname
을 사용할 수 없고, 따라서 오류가 발생하게 된다.- 클라이언트 측 상호작용이 불가능해짐
- 이 컴포넌트는 내비게이션 링크와 같은 UI 상호작용을 처리한다. 클라이언트 컴포넌트로 작동해야 하는 부분이기 때문에, 클라이언트에서 실행되어야 한다.
"use client";
가 없으면 이 컴포넌트가 서버에서만 실행되며, 브라우저에서의 상호작용이 제대로 작동하지 않을 수 있다.- 스타일링 및 상태 관리의 문제
clsx
를 사용한 조건부 클래스 설정이나,pathname
에 따라 스타일을 동적으로 변경하는 작업은 클라이언트 컴포넌트에서 실행될 때 제대로 작동한다. 서버에서는 이러한 상태 기반 로직을 실행할 수 없으므로, 원하는 UI 동작이 이루어지지 않을 수 있다.
- "use client";를 제거하면: 이 파일은 서버 컴포넌트로 간주된다. 클라이언트 측에서만 사용 가능한 훅(
usePathname
)이나 상태 관리 로직이 서버에서 실행되려 하기 때문에 오류가 발생하거나, UI 상호작용이 제대로 동작하지 않을 수 있다.- 위 코드에서
"use client";
는 필수적이다. 브라우저에서 실행되어야 하는 로직과 상호작용이 포함되어 있기 때문에, 클라이언트 컴포넌트로 명시적으로 지정해야 한다.
usePathname
이 클라이언트 컴포넌트에서만 가능한 이유는, 이 훅이 브라우저 환경에서만 사용할 수 있는 정보를 필요로 하기 때문! 이를 좀 더 구체적으로 설명하자면...
usePathname
의 역할
usePathname
은 Next.js에서 현재 URL 경로(현재 사용자가 보고 있는 페이지의 경로)를 가져오는 데 사용되는 훅이다. 예를 들어, 사용자가/dashboard/invoices
페이지를 보고 있다면,usePathname
은 이 경로를 반환한다.
- 브라우저(클라이언트):
- 브라우저는 사용자가 방문한 페이지의 URL을 알고 있으며, 이 정보를 기반으로 다양한 작업을 수행할 수 있다.
- 브라우저는
window.location.pathname
과 같은 API를 통해 현재 경로를 가져올 수 있다.
- 서버:
- 서버는 클라이언트로부터 요청을 받으면 그 요청을 처리하고, 그 결과를 클라이언트로 반환한다. 서버는 특정 요청에 대해 응답을 생성하지만, 클라이언트가 어떤 URL에서 페이지를 보는지 직접적으로 알지 못한다.
- 서버는 브라우저처럼
window
객체나 브라우저의 API를 사용할 수 없기 때문에, 클라이언트 측 경로 정보를 직접 접근하거나 처리할 수 없다.
usePathname
은 브라우저에서 현재 페이지의 경로를 가져오는 훅이다.- 브라우저에서만 동작하는
window.location.pathname
과 같은 기능을 사용하기 때문에, 이 훅은 클라이언트 컴포넌트에서만 실행될 수 있다.- 서버 컴포넌트는 브라우저의 상태에 접근할 수 없으므로, "use client"명시 안하면
usePathname
을 사용할 수 없다.