如何在Next.js Page Router中创建含中间参数的路由?
在Next.js Page Router中创建带动态参数的嵌套路由解决方案
当然可以创建这类路由,下面是具体的实现方案和注意事项:
一、正确的文件夹结构
要实现/services/${service.id}/subscriptions及同类子路由,你需要按照Page Router的动态路由规则组织pages目录:
pages/ └── services/ └── [serviceId]/ ├── subscriptions/ │ └── index.js # 对应路由 /services/{serviceId}/subscriptions ├── settings/ │ └── index.js # 对应路由 /services/{serviceId}/settings └── invoices/ └── index.js # 对应路由 /services/{serviceId}/invoices
其中[serviceId]是动态路由标识,方括号包裹的名称会被Next.js捕获为路由参数,你可以根据实际需求修改参数名(比如改成[sid],只要后续获取参数时对应上即可)。
二、获取动态参数serviceId
根据页面的渲染方式,有两种常用的参数获取方式:
1. 客户端组件使用useRouter钩子
在subscriptions/index.js这类子路由页面中,通过useRouter获取路由参数:
import { useRouter } from 'next/router'; export default function SubscriptionsPage() { const router = useRouter(); const { serviceId } = router.query; // 处理初始化时参数为空的情况 if (!serviceId) { return <div>加载中...</div>; } return ( <div> <h1>服务 {serviceId} 的订阅管理</h1> {/* 页面业务内容 */} </div> ); }
2. 服务端/静态生成页面使用getServerSideProps/getStaticProps
如果需要在服务端预获取数据,可通过context.params(Next.js 12+)或context.query(旧版本)获取参数:
export default function SubscriptionsPage({ serviceId, subscriptions }) { return ( <div> <h1>服务 {serviceId} 的订阅列表</h1> <ul> {subscriptions.map(sub => ( <li key={sub.id}>{sub.name}</li> ))} </ul> </div> ); } export async function getServerSideProps(context) { // 获取动态参数 const { serviceId } = context.params; // 调用API获取对应服务的订阅数据 const res = await fetch(`https://your-api-domain.com/services/${serviceId}/subscriptions`); const subscriptions = await res.json(); return { props: { serviceId, subscriptions, }, }; }
如果使用静态生成(getStaticProps),还需要配合getStaticPaths方法指定预渲染的serviceId列表,否则访问未预渲染的路由会返回404。
三、常见问题排查
- 确保动态路由文件夹名称严格使用
[参数名]格式,方括号不能遗漏 - 避免在
[serviceId]目录下创建同名文件(比如[serviceId].js和[serviceId]/文件夹同时存在会导致路由冲突) - 若使用
useRouter,注意在页面初始化阶段router.query可能为空,必须添加加载状态处理
内容的提问来源于stack exchange,提问作者Philipp Lehmann
相关产品推荐
相关产品推荐

