LESSON 07 · 約25分
動的ルートとページの移動
一覧から詳細へ。URLの値とLinkで画面をつなぎます。
コードを試す前に
基本演習はApp Router・JavaScript/JSX・Cache Components無効で進めます。11の有効化例は独立した発展実験です。01〜04は先に読んで、コードの実行は05の環境構築後に戻って試せます。
短い学習用の例です。各例は段階ごとの独立した例であり、全コードを一つのプロジェクトへ順に上書きして完成する形式ではありません。必要なファイル・依存関係・前提条件は注記に記載しています。
開発環境の準備を確認する →このレッスンでわかること
- [slug]から値を受け取れる
- Linkと通常のリンクを使い分けられる
一つのページ定義で、複数のURLを扱う
app/notes/[slug]/page.jsxは/notes/reactや/notes/routingのようなURLに対応します。[slug]はURLから値を受け取るための動的セグメントです。現行App Routerではparamsをawaitして読み取ります。
URLには場所と状態を持たせられる
パスの値と、?q=reactのような検索パラメーターは別です。共有したい検索条件やページ番号はURLに置くと、ブックマークや戻る操作に向きます。ページのsearchParamsも現行APIではawaitして読みます。
Linkで内部の移動をつなぐ
next/linkはアプリ内の移動の基本です。事前取得やクライアント側のナビゲーションを活用できます。実際の事前取得は本番環境やルートの性質などに依存します。フォーム送信など命令的な移動が必要な場面ではnext/navigationのAPIを検討します。
一覧と詳細で使う固定データ
export const notes = [
{ slug: 'react', title: 'Reactの基礎', body: '部品と状態から考えよう。' },
{ slug: 'routing', title: 'ルーティング', body: 'URLとページをつなごう。' },
]存在するノートだけを表示する詳細ページ
import Link from 'next/link'
import { notFound } from 'next/navigation'
import { notes } from '../../lib/notes'
export default async function NotePage({ params }) {
const { slug } = await params
const note = notes.find((item) => item.slug === slug)
if (!note) notFound()
return (
<main>
<h1>{note.title}</h1>
<p>{note.body}</p>
<Link href="/notes">一覧に戻る</Link>
</main>
)
}Cache Components無効の基本構成で使います。/notes/reactと/notes/routingが表示され、/notes/unknownはnotFound()へ進みます。有効な構成で試す場合は、動的処理のSuspense/loading境界なども必要です。
詳細へつながる一覧
import Link from 'next/link'
import { notes } from '../lib/notes'
export default function NotesPage() {
return (
<main>
<h1>ノート一覧</h1>
<ul>
{notes.map((note) => (
<li key={note.slug}>
<Link href={`/notes/${note.slug}`}>{note.title}</Link>
</li>
))}
</ul>
</main>
)
}TRY IT YOURSELF
一覧から詳細へ移動する
- 上記3ファイルを用意する
- Reactの基礎とルーティングのリンクをそれぞれ開く
- /notes/unknownを直接開き、存在しない場合も確認する
できたらOK:2つの詳細が同じpageから表示され、存在しないslugは404の表示へ進む
QUICK CHECK
理解を確かめよう
公式資料でもう少し詳しく
ここまで読めたら、ひとつ前進。