Menu

useRouter

useRouter フックを使用すると、Client Components内でプログラムによってルートを変更できます。

推奨: useRouter を使用する特定の要件がない限り、ナビゲーションには<Link> コンポーネントを使用してください。

app/example-client-component.tsx
TypeScript
'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(): 現在のルートをリフレッシュします。サーバーへの新しいリクエストを作成し、データリクエストを再取得し、Server Components を再レンダリングします。クライアントは、影響を受けていないクライアント側の React(例えば useState)またはブラウザ状態(例えばスクロール位置)を失わずに、更新された React Server Component ペイロードをマージします。
  • router.prefetch(href: string, options?: { onInvalidate?: () => void }): より高速なクライアント側の遷移のために、指定されたルートをプリフェッチします。オプションの onInvalidate コールバックは、プリフェッチされたデータが古くなったときに呼び出されます。
  • router.back(): ブラウザの履歴スタック内の前のルートに戻ります。
  • router.forward(): ブラウザの履歴スタック内の次のページに進みます。

補足:

  • 信頼できない、またはサニタイズされていない URL を router.push または router.replace に送信しないでください。クロスサイトスクリプティング(XSS)脆弱性にさらされる可能性があります。例えば、javascript: URL を router.push または router.replace に送信すると、ページのコンテキスト内で実行されます。
  • <Link> コンポーネントは、ルートがビューポート内に表示されると自動的にプリフェッチします。
  • refresh() は、フェッチリクエストがキャッシュされている場合は同じ結果を再現する可能性があります。cookiesheaders などの他の Dynamic APIs も応答を変更する可能性があります。
  • onInvalidate コールバックは、プリフェッチリクエストごとに最大 1 回呼び出されます。これは、更新されたルートデータの新しいプリフェッチをトリガーしたい場合を示します。

next/router からの移行

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

完全な移行ガイドを表示

ルータイベント

usePathnameuseSearchParams などの他の Client Component フックを組み合わせることで、ページ変更をリッスンできます。

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
TypeScript
'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.0導入時期:router.prefetch のオプション onInvalidate コールバック
v13.0.0導入時期:next/navigation からの useRouter