仕事で、Next.jsを使うことになって、Reactは独学していましたが、Next.jsは未経験だったのでチュートリアルからはじめています。
Reactの場合は、react-router-domを使って、App.jsにパスとコンポーネントをマッピングすることで、URLを解決させますが、Next.jsのPageフォルダに配置したファイル名がそのままURLになる点が異なります。
チュートリアルをやりながら、URL毎にファイルをつくらないといけないのかな?と疑問に思っていましたが、 Dynamic Routingという仕組みを作れば、同じようなファイルを複製しなくても良いので、今回はこれについて、記事にしています。
Dynamic Routingを使わない場合
- http://localhost:3000/p/hello-nextjs
- http://localhost:3000/p/learn-nextjs
- http://localhost:3000/p/deploy-nextjs
このような3つのページを動的に作り出したい場合、Dynamic Routingを使わない場合は、
/pages
└ /p
├ hello-nextjs.js
├ learn-nextjs.js
└ deploy-nextjs.js
のように3つのファイルを作成しないといけません。表示がほとんど同じ場合、かなり無駄です。
Dynamic Routingを使う場合
/pages
└ /p
└ [id].js
のように [ ]
で囲まれたファイルを1つ用意すればOKです。
カッコで囲まれたファイルを作成するのはかなり気持ちは悪いですが、Dynamic Routingを使っているんだとわかりやすくてよいのかもしれませんね。
コードも見ていきましょう。
- /pages/p/[id].js
import { useRouter } from 'next/router'
import Layout from '../../components/MyLayout.js'
const Post = () => {
const router = useRouter()
const { id } = router.query
return (
<Layout>
<h1>{id}</h1>
<p>This is the blog post content.</p>
</Layout>
)
}
export default Post
動的に渡されるファイル名を useRouter()
を使いh1のタイトルとして表示しています。
- /pages/index.js
import Layout from '../components/MyLayout.js'
import Link from 'next/link'
const PostLink = (props) => (
<li>
<Link href="/p/[id]" as={`/p/${props.id}`}>
<a>{props.id}</a>
</Link>
</li>
)
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
<PostLink id="hello-nextjs" />
<PostLink id="learn-nextjs" />
<PostLink id="deploy-nextjs" />
</ul>
</Layout>
)
}
Linkタグの hrefプロパティで、/pagesフォルダの対応するパスを指定して、asプロパティでURLを指定している。