ダイナミックルート
CoddyのReactジャーニー「Next.js の基本」セクションの一部 — レッスン 8/47。
40種類の料理があるmenuであっても、40個のフォルダを作成するわけではありません。/menu/pizza、/menu/pasta、/menu/tiramisuが、異なるデータを表示する同じpageになるようにしたいのです。
フォルダー名の中の角括弧(スクエアブラケット)には、そのような意味があります:
app/
menu/
[slug]/
page.jsx -> /menu/pizza
-> /menu/pasta
-> /menu/anything-at-all通常のフォルダはそのフォルダ名自身に一致します。[bracketed] フォルダは任意のセグメントに一致し、一致した内容を記憶します。括弧内の単語は後で読み取る際の名前になります。[slug] は slug を提供し、[id] は id を提供します。
Next はその値を params というプロップとしてページに渡します:
// app/menu/[slug]/page.jsx
export default async function Dish({ params }) {
const { slug } = await params;
return <h1>{slug}</h1>;
}その小さなファイルの中で、次の3つのことが起こっています。
- ページは
paramsプロップを受け取ります。すべてのページがこれを受け取り、動的ルートの場合は一致したセグメントが保持されます。 - Next 15において
paramsは Promise であるため、awaitする必要があります。それがコンポーネントがasyncになっている理由です。第5章でページが非同期になることが許可されている理由を説明しています。 - 分割代入によって
slugを取り出します。この名前はフォルダ名[slug]から直接付けられています。
/menu/pasta にアクセスすると、slug は "pasta" になります。1つのファイルで、すべての料理に対応できます。
チャレンジ
簡単動的フォルダはすでに存在しています: app/menu/[slug]/page.jsx は /menu 下のすべての URL に対応します。問題は、どの料理をリクエストしても pizza と表示されてしまうことです。
- コンポーネントを
asyncにします。 const { slug } = await params;で一致したセグメントを読み取ります。- ハードコードされたテキストの代わりに、
<h1 id="dish">内にslugをレンダリングします。
テストでは2つの異なる料理にアクセスし、2つの異なる見出しを期待します。
自分で試してみよう
import './globals.css';
export const metadata = {
title: 'My App',
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。