見出し画像

【Next.jsに触れてみよう。 】 #3 動的ルーティング

こんにちは!
ALH開発エンジニアのY.Nです。

この【Next.jsに触れてみよう。】シリーズも3回目です。
#2ではfile base routingによるページ遷移を紹介しました。(hello!と表示させたアレです。)

シリーズ過去作は下記リンクより見れます。

■ 【Next.jsに触れてみよう。】 #1 Next.jsとは?

【Next.jsに触れてみよう。】 #2 とりあえず立ち上げてみる


動的ルーティングを試してみる

今回は以下のようにurlが動的に変わるようなページを考えてみます。

/localhost:3000/
/localhost:3000/friends
/localhost:3000/friends/Taro

まずtopページがあり、See All Friends をクリックすると/friendsに遷移します。
friendsページには友達のリストが並んでいて対象の友達をクリックすると詳細情報のページに遷移します。
このような場合ルートは動的に変化し/friends/[対象の友達名]となるため静的なfile base routingだけでは表現できません。

そこでNext.jsでは以下のように動的ルーティングに対応しています。

実際に書いてみます。第1回にcreate-next-appで作成したプロジェクトそのまま使います
ざっくりとファイル構成

pages
 ├ _app.tsx
 ├ index.tsx
 ├ friends.tsx
 └ friends
   └ [name].tsx

top

pages/index.tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import Link from 'next/link'
import styles from '../styles/Home.module.css'

const Home: NextPage = () => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className={styles.main}>
        <h1 className={styles.title}>
          MyPage
        </h1>
        <div className={styles.grid}>
          <div className={styles.card}>
            <Link href="/friends">See All Friends</Link>
          </div>
        </div>
      </main>
      <footer className={styles.footer}>
      </footer>
    </div>
  )
}

export default Home

友達一覧

pages/friends.tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import Link from 'next/link'
import styles from '../styles/Home.module.css'

const FriendList: NextPage = () => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Friends</title>
      </Head>
      <main className={styles.main}>
        <h1 className={styles.title}>
          Friends
        </h1>
        <div className={styles.grid}>
          <div className={styles.card}>
            <Link href="/friends/Taro">Taro Yamada</Link>
          </div>
          <div className={styles.card}>
            <Link href="/friends/Hanako">Hanako Tanaka</Link>
          </div>
        </div>
      </main>
      <footer className={styles.footer}>
      </footer>
    </div>
  )
}

export default FriendList

ここで

<Link href="/friends/Taro">Taro Yamada</Link>
<Link href="/friends/Hanako">Hanako Tanaka</Link>

に注目してください
TaroとHanakoの詳細ページはURLは異なりますが、ページとしての枠組みは同じで表示するデータが変わるとします。

このような時、ファイル名を [ページ名].tsx とすることで、TaroとHanakoどちらのルートもキャッチできます。つまり↓

pages/friends/[name].tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import { useRouter } from 'next/router'
import styles from '../../styles/Home.module.css'

const FriendDetail: NextPage = () => {
  const router = useRouter()
  const name = router.query.name;
  return (
    <div className={styles.container}>
      <Head>
        <title>Friends</title>
      </Head>
      <main className={styles.main}>
        <h1 className={styles.title}>
          {name}&apos;s Profile
        </h1>
        <div className={styles.description}>
          welcome to {name}&apos;s Page
        </div>
      </main>
      <footer className={styles.footer}>
      </footer>
    </div>
  )
}

export default FriendDetail

ページのルートは/localhost:3000/friends/Taro
ファイルのルートは/pages/friends/[name].tsxとなってます。
この時"Taro"は[name].tsxでクエリとして扱うことができ、

const name = router.query.name;

のように取り出せます。
よって

<h1 className={styles.title}>
  {name}&apos;s Profile
</h1>

のようにすることで

このような動的なページ遷移が実現できるというわけです。
これで動的なルーティングの説明は以上です。
今回紹介した記法以外にも方法はあるので是非公式を確認してみてください。
有志の日本語化HPもあります。

次回

次はAPI Routingを紹介します。Taro's ProfileページにてTaroの情報をAPIで取得して表示してみます。





↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓


 ↓ ↓ ↓ ALHについてはこちら ↓ ↓ ↓


↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓