useRouter

useRouter 钩子允许您在 客户端组件 (Client Components) 中以编程方式更改路由。

推荐: 除非有特殊需求需要使用 useRouter,否则请优先使用 <Link> 组件 进行导航。

'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 }): 执行客户端导航至指定路由,并在 浏览器历史记录 (browser’s history) 栈中添加新条目。
  • router.replace(href: string, { scroll: boolean }): 执行客户端导航至指定路由,但不在 浏览器历史记录栈 (browser’s history stack) 中添加新条目。
  • router.refresh(): 刷新当前路由。向服务器发起新请求,重新获取数据并重新渲染服务端组件 (Server Components)。客户端会合并更新后的 React 服务端组件负载,同时保留不受影响的客户端 React 状态(如 useState)或浏览器状态(如滚动位置)。
  • router.prefetch(href: string): 预加载 (Prefetch) 指定路由以实现更快的客户端跳转。
  • router.back(): 导航至浏览器历史记录栈中的上一页。
  • router.forward(): 导航至浏览器历史记录栈中的下一页。

须知:

  • 请勿向 router.pushrouter.replace 传递未经验证或未净化的 URL,这可能导致跨站脚本 (XSS) 攻击。例如,传递给这些方法的 javascript: URL 会在页面上下文中执行。
  • <Link> 组件会在路由进入视口时自动预加载。
  • 如果 fetch 请求被缓存,refresh() 可能会产生相同的结果。其他动态 API 如 cookiesheaders 也可能改变响应。

next/router 迁移

  • 使用应用路由 (App Router) 时,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 边界 中,因为在 静态渲染 (static rendering) 期间,useSearchParams() 会导致客户端渲染直至最近的 Suspense 边界。了解更多

禁用滚动至顶部

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

'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>
  )
}

版本历史

版本变更说明
v13.0.0引入了从 next/navigation 导入的 useRouter

On this page