useSelectedLayoutSegment
useSelectedLayoutSegment
는 호출된 Layout의 한 단계 아래에 있는 활성 경로 세그먼트를 읽을 수 있게 해주는 클라이언트 컴포넌트 훅입니다.
이는 활성 자식 세그먼트에 따라 스타일이 변경되는 부모 레이아웃 내의 탭과 같은 네비게이션 UI에 유용합니다.
app/example-client-component.tsx
"use client";
import { useSelectedLayoutSegment } from "next/navigation";
export default function ExampleClientComponent() {
const segment = useSelectedLayoutSegment();
return <p>Active segment: {segment}</p>;
}
app/example-client-component.js
"use client";
import { useSelectedLayoutSegment } from "next/navigation";
export default function ExampleClientComponent() {
const segment = useSelectedLayoutSegment();
return <p>Active segment: {segment}</p>;
}
알아두면 좋은 점:
useSelectedLayoutSegment
는 클라이언트 컴포넌트 훅이고, 레이아웃은 기본적으로 서버 컴포넌트이므로,useSelectedLayoutSegment
는 일반적으로 레이아웃으로 가져오는 클라이언트 컴포넌트를 통해 호출됩니다.useSelectedLayoutSegment
는 한 단계 아래의 세그먼트만 반환합니다. 모든 활성 세그먼트를 반환하려면useSelectedLayoutSegments
를 참조하세요.
매개변수
const segment = useSelectedLayoutSegment(parallelRoutesKey?: string)
useSelectedLayoutSegment
는 선택적으로 parallelRoutesKey
를 받습니다. 이를 통해 해당 슬롯 내의 활성 경로 세그먼트를 읽을 수 있습니다.
반환값
useSelectedLayoutSegment
는 활성 세그먼트의 문자열을 반환하거나, 존재하지 않는 경우 null
을 반환합니다.
예를 들어, 아래의 레이아웃과 URL이 주어졌을 때, 반환되는 세그먼트는 다음과 같습니다:
레이아웃 | 방문한 URL | 반환된 세그먼트 |
---|---|---|
app/layout.js | / | null |
app/layout.js | /dashboard | 'dashboard' |
app/dashboard/layout.js | /dashboard | null |
app/dashboard/layout.js | /dashboard/settings | 'settings' |
app/dashboard/layout.js | /dashboard/analytics | 'analytics' |
app/dashboard/layout.js | /dashboard/analytics/monthly | 'analytics' |
예시
활성 링크 컴포넌트 만들기
useSelectedLayoutSegment
를 사용하여 활성 세그먼트에 따라 스타일이 변경되는 활성 링크 컴포넌트를 만들 수 있습니다. 예를 들어, 블로그 사이드바의 추천 게시물 목록:
app/blog/blog-nav-link.tsx
"use client";
import Link from "next/link";
import { useSelectedLayoutSegment } from "next/navigation";
// 이 *클라이언트* 컴포넌트는 블로그 레이아웃으로 가져올 것입니다
export default function BlogNavLink({
slug,
children,
}: {
slug: string;
children: React.ReactNode;
}) {
// `/blog/hello-world`로 이동하면 선택된 레이아웃 세그먼트로
// 'hello-world'를 반환합니다
const segment = useSelectedLayoutSegment();
const isActive = slug === segment;
return (
<Link
href={`/blog/${slug}`}
// 링크가 활성 상태인지에 따라 스타일 변경
style={{ fontWeight: isActive ? "bold" : "normal" }}
>
{children}
</Link>
);
}
app/blog/blog-nav-link.js
"use client";
import Link from "next/link";
import { useSelectedLayoutSegment } from "next/navigation";
// 이 *클라이언트* 컴포넌트는 블로그 레이아웃으로 가져올 것입니다
export default function BlogNavLink({ slug, children }) {
// `/blog/hello-world`로 이동하면 선택된 레이아웃 세그먼트로
// 'hello-world'를 반환합니다
const segment = useSelectedLayoutSegment();
const isActive = slug === segment;
return (
<Link
href={`/blog/${slug}`}
// 링크가 활성 상태인지에 따라 스타일 변경
style={{ fontWeight: isActive ? "bold" : "normal" }}
>
{children}
</Link>
);
}
app/blog/layout.tsx
// 클라이언트 컴포넌트를 부모 레이아웃(서버 컴포넌트)으로 가져오기
import { BlogNavLink } from "./blog-nav-link";
import getFeaturedPosts from "./get-featured-posts";
export default async function Layout({
children,
}: {
children: React.ReactNode;
}) {
const featuredPosts = await getFeaturedPosts();
return (
<div>
{featuredPosts.map((post) => (
<div key={post.id}>
<BlogNavLink slug={post.slug}>{post.title}</BlogNavLink>
</div>
))}
<div>{children}</div>
</div>
);
}
app/blog/layout.js
// 클라이언트 컴포넌트를 부모 레이아웃(서버 컴포넌트)으로 가져오기
import { BlogNavLink } from "./blog-nav-link";
import getFeaturedPosts from "./get-featured-posts";
export default async function Layout({ children }) {
const featuredPosts = await getFeaturedPosts();
return (
<div>
{featuredPosts.map((post) => (
<div key={post.id}>
<BlogNavLink slug={post.slug}>{post.title}</BlogNavLink>
</div>
))}
<div>{children}</div>
</div>
);
}
버전 기록
버전 | 변경 사항 |
---|---|
v13.0.0 | useSelectedLayoutSegment 도입됨. |