动态路由
本课属于 Coddy React 学习旅程的“Next.js 基础”单元。第 8 课,共 47 课。
有 40 道菜的菜单,不需要建 40 个文件夹。你希望 /menu/pizza、/menu/pasta 和 /menu/tiramisu 指向同一个页面,并显示不同的数据。
文件夹名称中的方括号就是这个意思:
app/
menu/
[slug]/
page.jsx -> /menu/pizza
-> /menu/pasta
-> /menu/anything-at-all普通文件夹会匹配与其名称相同的内容。[bracketed] 文件夹可以匹配任意片段,并记住匹配到的内容。方括号内的词就是之后读取匹配内容时使用的名称:[slug] 会给你 slug,[id] 会给你 id。
接下来,会将该值作为名为 params 的属性传递给页面:
// app/menu/[slug]/page.jsx
export default async function Dish({ params }) {
const { slug } = await params;
return <h1>{slug}</h1>;
}这个小文件里会发生三件事:
- 页面会接收一个
params属性。每个页面都会有一个这样的属性,对于动态路由,它包含匹配的路径段。 - 在 Next 15 中,
params是一个 Promise,所以你需要await它。这就是组件要使用async的原因。第 5 章会解释为什么页面可以这样写。 - 解构会取出
slug,它的名字直接来自文件夹[slug]。
访问 /menu/pasta,此时 slug 的值是 "pasta"。一个文件,包含所有菜品。
挑战
简单动态文件夹已经存在:app/menu/[slug]/page.jsx 可以处理 /menu 下的所有 URL。问题是,无论你请求哪道菜,它都显示 pizza。
- 将组件设为
async。 - 使用
const { slug } = await params;读取匹配的路径段。 - 在
<h1 id="dish">中渲染slug,而不是硬编码文本。
测试会访问两道不同的菜,并期待两个不同的标题。
亲手试试
import './globals.css';
export const metadata = {
title: 'My App',
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。