usePathname
usePathname 是一个 Client Component hook,它允许你读取当前 URL 的 pathname。
值得注意的是:当启用
cacheComponents时,如果你的路由具有动态参数,usePathname可能需要在其周围使用Suspense边界。如果你使用generateStaticParams,Suspense边界是可选的
'use client'
import { usePathname } from 'next/navigation'
export default function ExampleClientComponent() {
const pathname = usePathname()
return <p>Current pathname: {pathname}</p>
}usePathname 有意要求使用 Client Component。需要注意的是,Client Components 并不是一种反优化。它们是 Server Components 架构的一个组成部分。
例如,带有 usePathname 的 Client Component 将在初始页面加载时渲染为 HTML。当导航到新路由时,此组件不需要重新获取。相反,该组件只会下载一次(在客户端 JavaScript bundle 中),并根据当前状态重新渲染。
值得注意的是:
- 不支持从 Server Component 读取当前 URL。这种设计是有意为之,目的是支持在页面导航之间保留布局状态。
- 如果你的页面被静态预渲染,并且你的应用在
next.config中有 rewrites 或 Proxy 文件,使用usePathname()读取 pathname 可能会导致 hydration 不匹配错误——因为初始值来自服务器,可能与路由后实际的浏览器 pathname 不匹配。请参阅我们的示例以了解缓解此问题的方法。
与 Pages Router 的兼容性
如果你的组件使用 usePathname 并且它们被导入到 Pages Router 中的路由,请注意,如果 router 尚未初始化,usePathname 可能会返回 null。这可能发生在诸如 fallback 路由或 Pages Router 中的自动静态优化等情况下。
为了增强路由系统之间的兼容性,如果你的项目同时包含 app 和 pages 目录,Next.js 将自动调整 usePathname 的返回类型。
参数
const pathname = usePathname()usePathname 不接受任何参数。
返回值
usePathname 返回当前 URL 的 pathname 字符串。例如:
| URL | 返回值 |
|---|---|
/ | '/' |
/dashboard | '/dashboard' |
/dashboard?v=2 | '/dashboard' |
/blog/hello-world | '/blog/hello-world' |
示例
响应路由变化执行某些操作
'use client'
import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
function ExampleClientComponent() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
// Do something here...
}, [pathname, searchParams])
}避免使用 rewrites 时的 hydration 不匹配
当页面被预渲染时,HTML 是为源 pathname 生成的。如果随后通过使用 next.config 或 Proxy 的 rewrite 访问该页面,浏览器 URL 可能会不同,而 usePathname() 将在客户端读取重写后的 pathname。
为了避免 hydration 不匹配,请设计 UI,使得只有一小部分隔离的部分依赖于客户端 pathname。在服务器上渲染一个稳定的 fallback,并在挂载后更新该部分。
'use client'
import { useEffect, useState } from 'react'
import { usePathname } from 'next/navigation'
export default function PathnameBadge() {
const pathname = usePathname()
const [clientPathname, setClientPathname] = useState('')
useEffect(() => {
setClientPathname(pathname)
}, [pathname])
return (
<p>
Current pathname: <span>{clientPathname}</span>
</p>
)
}| 版本 | 变更 |
|---|---|
v13.0.0 | 引入 usePathname。 |