useSelectedLayoutSegment 是一个 客户端组件 钩子,它允许你读取在其被调用的 Layout 下一级 的活跃路由段。
它对于导航UI很有用,例如父布局中的选项卡可以根据活跃的子段改变样式。
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default function ExampleClientComponent() {
const segment = useSelectedLayoutSegment()
return <p>Active segment: {segment}</p>
}'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default function ExampleClientComponent() {
const segment = useSelectedLayoutSegment()
return <p>Active segment: {segment}</p>
}提示:
- 由于
useSelectedLayoutSegment是一个 客户端组件 钩子,并且 Layouts 默认是 服务端组件,因此useSelectedLayoutSegment通常通过一个导入到 Layout 中的客户端组件来调用。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 来创建一个活跃链接组件,该组件会根据活跃路由段改变样式。例如,博客侧边栏中特色文章列表:
'use client'
import Link from 'next/link'
import { useSelectedLayoutSegment } from 'next/navigation'
// This *client* component will be imported into a blog layout
export default function BlogNavLink({
slug,
children,
}: {
slug: string
children: React.ReactNode
}) {
// Navigating to `/blog/hello-world` will return 'hello-world'
// for the selected layout segment
const segment = useSelectedLayoutSegment()
const isActive = slug === segment
return (
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}'use client'
import Link from 'next/link'
import { useSelectedLayoutSegment } from 'next/navigation'
// This *client* component will be imported into a blog layout
export default function BlogNavLink({ slug, children }) {
// Navigating to `/blog/hello-world` will return 'hello-world'
// for the selected layout segment
const segment = useSelectedLayoutSegment()
const isActive = slug === segment
return (
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}// Import the Client Component into a parent Layout (Server Component)
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>
)
}// Import the Client Component into a parent Layout (Server Component)
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 引入。 |