跳到主要内容

useRouter

useRouter 钩子允许你在 客户端组件 中以编程方式更改路由。

建议:除非你有使用 useRouter 的特定要求,否则请使用 <Link> 组件 进行导航。

app/example-client-component.tsx
'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
const router = useRouter()

return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}

useRouter()

  • router.push(href: string, { scroll: boolean }):执行客户端导航到提供的路由。在 浏览器历史记录 堆栈中添加一个新条目。
  • router.replace(href: string, { scroll: boolean }):执行客户端导航到提供的路由,而不在 浏览器历史记录堆栈 中添加新条目。
  • router.refresh():刷新当前路由。向服务器发出新请求,重新获取数据请求,并重新渲染服务端组件。客户端将合并更新的 React 服务端组件负载,而不会丢失未受影响的客户端 React(例如 useState)或浏览器状态(例如滚动位置)。
  • router.prefetch(href: string, options?: { onInvalidate?: () => void })预取 提供的路由以实现更快的客户端转换。当 预取数据变得过时 时,会调用可选的 onInvalidate 回调。
  • router.back():导航到浏览器历史记录堆栈中的上一个路由。
  • router.forward():导航到浏览器历史记录堆栈中的下一页。

提示

  • 你不应该向 router.pushrouter.replace 发送不受信任或未清理的 URL,因为这可能会让你的站点面临跨站脚本(XSS)漏洞。例如,发送到 router.pushrouter.replacejavascript: URL 将在你的页面上下文中执行。
  • <Link> 组件会在路由在视口中可见时自动预取路由。
  • 如果 fetch 请求被缓存,refresh() 可能会产生相同的结果。其他动态 API 如 cookiesheaders 也可能会改变响应。
  • onInvalidate 回调在每个预取请求中最多调用一次。它表示何时你可能想要触发新的预取以获取更新的路由数据。

next/router 迁移

  • 使用 App 路由器时,useRouter 钩子应该从 next/navigation 导入,而不是 next/router
  • pathname 字符串已被移除,由 usePathname() 替代
  • query 对象已被移除,由 useSearchParams() 替代
  • router.events 已被替换。见下文。

查看完整迁移指南

示例

路由器事件

你可以通过组合其他客户端组件钩子(如 usePathnameuseSearchParams)来监听页面更改。

app/components/navigation-events.js
'use client'

import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'

export function NavigationEvents() {
const pathname = usePathname()
const searchParams = useSearchParams()

useEffect(() => {
const url = `${pathname}?${searchParams}`
console.log(url)
// 你现在可以使用当前 URL
// ...
}, [pathname, searchParams])

return '...'
}

可以导入到布局中。

app/layout.js
import { Suspense } from 'react'
import { NavigationEvents } from './components/navigation-events'

export default function Layout({ children }) {
return (
<html lang="en">
<body>
{children}

<Suspense fallback={null}>
<NavigationEvents />
</Suspense>
</body>
</html>
)
}

提示<NavigationEvents> 被包装在 Suspense 边界 中,因为 useSearchParams()静态渲染 期间会导致客户端渲染到最近的 Suspense 边界。了解更多

禁用滚动到顶部

默认情况下,Next.js 在导航到新路由时会滚动到页面顶部。你可以通过向 router.push()router.replace() 传递 scroll: false 来禁用此行为。

app/example-client-component.tsx
'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
const router = useRouter()

return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}

版本历史

版本更改
v15.4.0router.prefetch 引入了可选的 onInvalidate 回调
v13.0.0引入了来自 next/navigationuseRouter