什么是动态路由?
动态路由指的是 URL 中的某些部分不是固定的,而是可以动态变化的。比如,你有一个用户详情页面,可能每个用户的 URL 都是 http://example.com/users/123,其中 123 是用户的 ID。通过动态路由,我们可以捕获这个 ID 并展示对应的用户信息。
一、创建动态路由文件
在 Next.js 中,动态路由的核心是方括号表示法。我们通过在 pages 目录下创建以方括号包裹的文件来定义动态路由。
例如,我们要为用户创建一个详情页面,路径形如 /users/[id].js,其中 [id] 是用户的唯一标识符。
1. 创建 users 文件夹
在 pages 目录下创建一个 users 文件夹:
/pages/users/[id].js
2. 编写动态路由页面
我们可以通过 useRouter 钩子获取 URL 中的动态参数。在这个例子中,我们将根据 id 展示不同的用户详情。
// pages/users/[id].js
import { useRouter } from 'next/router';
const UserDetails = () => {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>User Details</h1>
<p>Displaying details for user ID: {id}</p>
</div>
);
};
export default UserDetails;
在这个页面中,router.query.id 代表 URL 中的 id 参数。我们可以通过它来显示不同用户的详情。
3. 访问动态页面
启动开发服务器后,访问 http://localhost:3000/users/123,页面将会显示:
Displaying details for user ID: 123
二、基于动态参数获取数据
通常,动态路由不仅仅是显示动态参数,还需要根据这些参数获取数据。比如,在用户详情页,我们可能需要根据用户 ID 从数据库或 API 获取用户的详细信息。
在 Next.js 中,我们可以使用 getServerSideProps 或 getStaticProps 来预获取数据。以下是一个使用 getServerSideProps 获取用户数据的示例:
// pages/users/[id].js
import { useRouter } from 'next/router';
const UserDetails = ({ user }) => {
const router = useRouter();
// 如果页面还在加载,返回加载中的提示
if (router.isFallback) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
</div>
);
};
export async function getServerSideProps(context) {
const { id } = context.params;
// 模拟 API 请求
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const user = await res.json();
// 如果用户不存在,返回 404 页面
if (!user) {
return {
notFound: true,
};
}
return {
props: { user },
};
}
export default UserDetails;
解释:
- getServerSideProps: 我们使用
getServerSideProps来根据用户 ID 获取数据。每次请求页面时,Next.js 都会在服务器端运行此函数,并将返回的数据作为props传递给组件。 - context.params:
context.params包含动态路由参数,也就是 URL 中的id。 - API 请求: 我们模拟了一个 API 请求来获取用户数据。
访问页面
访问 http://localhost:3000/users/1,页面将展示对应用户的详细信息:
Name: Leanne Graham
Email: Sincere@april.biz
三、动态嵌套路由
Next.js 也支持嵌套路由。假设我们有一个用户管理系统,其中每个用户有多个订单。我们可以通过嵌套路由来实现 /users/[id]/orders 这样的页面结构。
- 在
pages/users/[id]/目录下创建orders.js:
/pages/users/[id]/orders.js
- 编写订单页面逻辑:
import { useRouter } from 'next/router';
const UserOrders = () => {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>Orders for User {id}</h1>
{/* 这里可以展示订单列表 */}
</div>
);
};
export default UserOrders;
访问嵌套路由页面
访问 http://localhost:3000/users/1/orders,页面将显示:
Orders for User 1