💬
Next.js App Routerにおけるページ遷移について
業務でNext.jsに触る機会が多くリンク周りに使える物が多くて混乱したのでドキュメントを読みまとめてみる。
概要
- Next.jsでリンク遷移やページのナビゲーションをやる方法は以下の四つがある
-
<Link>
コンポーネント: 基本的にはnext/link
のこれを使うのがパフォーマンス良さそう。ドキュメントでも<Link>
コンポーネントの使用を推奨している。 -
useRouter()
hook: ルーティングを柔軟に操作したい場合に使用する。クライアントコンポーネント内で使用できる。 -
redirect
function - ネイティブのHistory API
<Link>
コンポーネントについて
<Link>
コンポーネントはHTMLの<a>タグを拡張したもので、href
プロパティを渡して使用できる。ページが表示される際に自動的にプリフェッチされ、ユーザーのビューポートに入ると事前にリンク先のデータが読み込まれる。
コード例
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
useRouter()
hook (Client Components)
クライアントコンポーネント内で、プログラム的にナビゲーションを制御したい場合はuseRouter()
フックを使用する。page routerの場合はnext/router
からインポートし、app routerの場合は、next/navigation
からインポートする。
ボタンのクリックによるナビゲーションや未ログインユーザを特定のページにリダイレクトしたい時など、<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>
)
}
redirect
function (Server Components)
サーバーコンポーネント内でのリダイレクトにはredirect
関数を使用する。絶対URLも使えるため、外部リンクへのリダイレクトにも使用できる。デフォルトではステータスコード 307を返す。また、redirect
は内部的にエラーをスローするため、try/catch
ブロックの外で呼び出す必要がある。
コード例
import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }: { params: { id: string } }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
native History API
- Next.jsはネイティブのHistory API
window.history.pushState
とwindow.history.replaceState
を使える。上記の<Link>
やuseRouter
では対応できない場合に使用。
参考文献
Discussion