Menu
CoddyTech

动态路由

本课属于 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"。一个文件,包含所有菜品。

challenge icon

挑战

简单

动态文件夹已经存在:app/menu/[slug]/page.jsx 可以处理 /menu 下的所有 URL。问题是,无论你请求哪道菜,它都显示 pizza。

  1. 将组件设为 async。
  2. 使用 const { slug } = await params; 读取匹配的路径段。
  3. 在 <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>
    );
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

Next.js 基础中的所有课