メインコンテンツまでスキップ

useRouter

useRouterフックはClient Components内部でプログラム的にルートを変更することができます。

推奨: 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 }): 指定されたルートへクライアントサイドナビゲーションを実行します。新しいエントリをbrowserの履歴スタックに追加します
  • router.replace(href: string, { scroll: boolean }): 指定されたルートへクライアントサイドナビゲーションを実行しますが、browserの履歴スタックに新しいエントリを追加しません
  • router.refresh(): 現在のルートを更新します。サーバーへの新しいリクエストを行い、データリクエストを再フェッチし、Server Componentsを再レンダリングします。クライアントは、影響を受けないクライアントサイドのReact(例:useState)やブラウザの状態(例:スクロール位置)を失わずに、更新されたReact Server Componentペイロードをマージします
  • router.prefetch(href: string): クライアントサイドでの移行をより速くするために、指定されたルートをプリフェッチします
  • router.back(): browserの履歴スタック内の前のルートに戻ります
  • router.forward(): browserの履歴スタック内の次のページに進みます

Good to know:

  • <Link>コンポーネントはビューポートに表示されると自動的にルートをプリフェッチします
  • refresh()は、フェッチリクエストがキャッシュされている場合、同じ結果を再生産する可能性があります。他の動的API、例えばcookiesheadersは応答を変更する可能性があります

next/routerからの移行

  • useRouterフックは、App Routerを使用する際にはnext/navigationからインポートする必要があります
  • pathname文字列は削除され、usePathname()で置き換えられました
  • queryオブジェクトは削除され、useSearchParams()で置き換えられました
  • router.eventsは置き換えられました。以下を参照

全文の移行ガイドを読む

Router events

他のClient Componentフックである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>
)
}

Good to know: <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>
)
}

バージョン履歴

バージョン変更
v13.0.0next/navigationからのuseRouterが導入されました