NextJS 动态路由综合指南
本文是整个 Next.js 系列文章的一部分,我整理这些文章旨在帮助您成为 Next.js 专业人士并开始构建超快的 React 应用程序。 💡 如果您不想错过任何教程,请通过单击此处或前往DailyDev.io注册我的时事通讯以获取更多信息。 在这个问题上,我们将学习 Next.js 如何使我们能够轻松地从单个 React 组件创建动态页面。 💡 你可以在这里找到这个项目的源代码。 所以让我
本文是整个 Next.js 系列文章的一部分,我整理这些文章旨在帮助您成为 Next.js 专业人士并开始构建超快的 React 应用程序。
💡 如果您不想错过任何教程,请通过单击此处或前往DailyDev.io注册我的时事通讯以获取更多信息。
在这个问题上,我们将学习 Next.js 如何使我们能够轻松地从单个 React 组件创建动态页面。
💡 你可以在这里找到这个项目的源代码。
所以让我们开始吧!
先决条件
-
节点≥12
-
反应基础
快速回顾
上次我们在这里创建了一个基本的 Web 应用程序,以更好地了解如何使用 Next.js 构建应用程序的基础知识。
我们介绍了pages
的概念以及 Next.js 如何期望我们为我们的应用程序和React
组件搭建基架,以便它自动创建和管理页面 URL 和转换。
如果您错过了该介绍性问题,我强烈建议您在继续之前检查一下。
页
在 Next.js 中,每个页面都是一个 React 组件,它是从位于项目根目录的/pages
目录中的文件中导出的。文件的名称决定了它将关联的路由,包括 React 组件所在的文件夹(如果有)。
-
/pages/index.tsx
映射到/
路由(特殊文件) -
/pages/dogs/a-doggo.tsx
映射到/dogs/a-doggo.tsx
路由。
新文件的内容可以是您想要的任何内容,只要它导出一个默认的 React 组件,该组件呈现一些 JSX,然后 Next.js 可以将其呈现为 HTML。
生成我们的项目
首先,我们将创建我们的 Next.js 项目来托管此应用程序,方法是在您希望存储所有出色 Next.js 项目的目录中运行此命令。
npx create-next-app nextjs-dynamic-routing --use-npm --typescript -e https://github.com/igorasilveira/blog-examples/tree/main/nextjs-basic-routing
进入全屏模式 退出全屏模式
我们刚刚做的事情的细目:
-
npx
- 是一个命令行界面工具,可以轻松执行 npm 包,而无需将它们实际安装在您自己的机器上。 -
create-next-app
- 我们最好的朋友,将为您搭建一个完美平衡的 Next.js 应用程序。 -
nextjs-dynamic-routing
- 这是我决定给我的项目起的名字,随意混合一下。 -
--use-npm
- 这个标志指定我们想使用 NPM 作为我们的依赖管理器。 -
--typescript
- 这个标志告诉脚手架工具我们要生成一个 TypeScript 项目并初始化所有必需的依赖项(这更多是我的个人偏好 - ❤️ TypeScript)。 -
-e
- 此选项指定引导应用程序的示例。在这种情况下,我们使用上一期的 GitHub 存储库,以便我们可以从上次中断的地方继续构建我们的应用程序。
运行我们的应用程序
我们的 Next.js 项目已经创建并自动安装了所有依赖项。我们现在可以运行它并看到我们的应用程序变得生动起来!为此,在我们用于生成项目的同一终端中,我们现在将cd
放入我们的项目文件夹并运行以下命令以开发模式启动我们的项目。
npm run dev
进入全屏模式 退出全屏模式
几秒钟后,您的 Next.js 应用程序服务器将启动(希望成功),您现在可以导航到http://localhost:3000
并检查我们基于 doggo 的应用程序! 🐶
[](https://res.cloudinary.com/practicaldev/image/fetch/s--30McaciC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/y1c7eki3jwwrei6sg3io.png)
动态路由
现在我们已经启动并运行了我们的应用程序,让我们更多地了解什么是动态路由,我们为什么需要它,以及 Next.js 如何为客户端呈现的页面处理它。
为什么我们需要它
像我们在上一个教程中使用的预定义的基于路径的路由并不总是大型复杂和动态应用程序的最佳选择。
如果我们保持以前的方法,每次我们想要创建一个新页面时都会涉及到创建一个 React 组件,这需要应用程序的开发人员创建新代码,将其推送到主分支,然后将更改部署到生产环境.这不仅是 CI/CD 的噩梦,因为它也是重复意大利面条代码的秘诀。
例如,在我们的 doggo 应用程序中,每次我们想向应用程序添加新的 dog 页面时,我们不想复制之前的组件并进行必要的更改以反映新添加的内容,尤其是因为我们所有的 doggos 页面都呈现完全相同的结构。这是组件可重用性的完美用例。
组件可重用性
如果您之前在 Web 旅程中使用过 Components,那么您已经熟悉了它们的好处。
组件允许您定义通用应用程序的结构,然后您可以轻松地重用这些结构,而无需重新编写它们的外观和行为。然后,您可以按照您希望的任何方式排列这些组件,以形成更大、更复杂的组件,最终成为构建完整应用程序页面的部分。如果以后您希望更改该结构、设计或功能,您只需要更新您想要的组件,这些更改将反映在使用它们的任何地方。
[](https://res.cloudinary.com/practicaldev/image/fetch/s--bD3JJG-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/b91m0iqyszi6lr2dgqze.png)
Next.js 如何处理它
在 Next.js 中,您可以做到这一点(与任何现代 Web 框架一样),最后,您只需从单个导出的 React 组件 就为您的应用程序提供一个可重用页面。稍后,如果您需要更改应用程序中的每个 doggo 页面,您只需在单个文件中更新一个组件。
为了生成动态(可重用)页面,我们需要对之前的 React 组件 进行一些更改和添加,以便 Next.js 可以理解它实际上是动态路由而不是静态路由一。
这一切都从pages
文件夹中的文件名开始,与以前相同,但这次有所不同。动态(可重用)页面将从括号 ([param]
) 包围的特殊命名文件中导出。路由的其余部分仍然由我们在上一篇文章中讨论的文件夹层次结构定义。让我们看一些例子:
-
pages/dogs/[id].tsx
→/dogs/:id
(/dogs/123
) -
pages/post/[...all].tsx
→/post/*
(/post/2020/id/title
)
如果我们考虑第一个示例pages/dogs/[id].tsx
,任何匹配/dogs/:id
模式的路由都将由pages/dogs
目录中的特殊[id].tsx
页面导出的 React 组件 渲染,例如/dogs/123
和/dogs/russel
。
[](https://res.cloudinary.com/practicaldev/image/fetch/s--GxTwR_mY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/dncnw6axzx5jcgdml76z.png)
要访问路由的动态部分(本例中为id
),我们可以直接访问 Next.js Router 并通过query
对象获取。在/dogs/russel
的示例中,query
对象将如下所示:
{ "id": "russel" }
进入全屏模式 退出全屏模式
要在您的 React 组件 中访问它,您将使用提供的 Next.js 挂钩useRouter
。
[](https://res.cloudinary.com/practicaldev/image/fetch/s--ab7yAbvw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6ejybc1pdne1r1ko7134.png)
更新我们的 Doggo 应用程序
让我们考虑我们在第一个教程中构建的狗应用程序,其中我们有一个文件为每只狗导出一个 React 组件:
[](https://res.cloudinary.com/practicaldev/image/fetch/s--mFCZqEDc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/3j1ty93uqawhprlrp4xs.png)
您可以看到,一旦我们进入数百只狗的数十个,这将如何迅速成为管理的噩梦。所以让我们改用 Dynamic Routing 来只需要管理一个文件。
创建特殊的[id].tsx
文件
为了保留我们 doggo 页面的先前结构,但仍重构为使用 Dynamic Routing,我们可以简单地将其中一个文件重命名为[id].tsx
并删除所有其他呈现单个 dog 的文件。我们可以保留index.tsx
文件,因为它有不同的用途,并且无论如何都不会匹配我们正在创建的动态路由。
所以最终的结果应该是这样干净的:
[](https://res.cloudinary.com/practicaldev/image/fetch/s--vOFuM-Oz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/u9h6ino7frhi9kzks6wv.png)
现在,每条/dogs/:id
路线都将由该单个[id].tsx
文件呈现,而不需要为每只狗创建一个文件。完美的!
更新文件内容
我们现在可以对新更新的特殊文件进行更改,以便我们可以实际看到每个页面上传递的动态id
。
为此,我们将通过query
对象访问id
,然后通过将其添加到之前的h1
标记将其呈现在屏幕上。
import type { NextPage } from "next";
import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
const Doggo: NextPage = () => {
const router = useRouter(); // -> Access Next.js Router here
const { id } = router.query;
return (
<div>
<Head>
<title>A Doggo</title>
</Head>
<main>
{/* // -> Render the id on the screen */}
<h1>This is Doggo: {id}.</h1>
<Image
alt="This is a doggo"
src="https://loremflickr.com/520/520/dog"
width={520}
height={520}
/>
<p style={{ color: "#0070f3" }}>
<Link href="/">Back Home</Link>
</p>
</main>
</div>
);
};
export default Doggo;
进入全屏模式 退出全屏模式
伟大的!现在我们可以根据提供的路线在每个狗页面上看到不同的内容。这有多棒? 😎
[](https://res.cloudinary.com/practicaldev/image/fetch/s--RH14GZP---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/71ho39cywhgmhjnrhv10.png)
最终结果
经过您的辛勤工作,这是您的 doggo 应用程序的预期结果。看起来已经很棒了!
[](https://res.cloudinary.com/practicaldev/image/fetch/s--vuNDp0k4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/ch0zkjot7g7vx4lud1op.gif)
最后备注
现在您已经有了一个可以运行的动态 doggo 应用程序,您可以尝试开发单个 dog 页面,以便在给定 id 的情况下动态获取更多信息,或者测试创建新目录和更复杂的动态路由。如果您遇到任何问题,请随时通过Twitter与我联系,我的 DM 始终开放。
后续步骤: 请留意我的以下 Next.js 教程,我们将在其中介绍_静态生成的动态路由_(高性能动态网页的下一步)等等!如果您不想错过任何教程,请通过单击此处注册我的时事通讯。
更多推荐
所有评论(0)