
在 React Router v6.9.0 中,需通过单个带 /* 的父路由配合相对路径子路由实现动态渲染;直接复用绝对路径会导致嵌套失配,正确做法是将子路由路径设为相对于父路由的“相对路径”,并移除重复的路径前缀。
在 react router v6.9.0 中,需通过单个带 `/*` 的父路由配合相对路径子路由实现动态渲染;直接复用绝对路径会导致嵌套失配,正确做法是将子路由路径设为相对于父路由的“相对路径”,并移除重复的路径前缀。
React Router v6 彻底重构了路由匹配逻辑,与 v5 的 exact、switch 等概念不同,v6 默认采用嵌套式相对匹配(nested relative matching)。这意味着:子
✅ 正确结构:单父路由 + 相对子路径
首先,将顶层路由收敛为一个通配父路由,避免重复定义 ui/forms/new 和 ui/forms/:id:
// App.tsx(根路由配置)
return (
<browserrouter><routes><route path="ui/forms/*" element="{" i18n="{i18n}"><formeditor></formeditor>
}
/>
</route></routes></browserrouter>
);
此时,所有以 /ui/forms/ 开头的 URL(如 /ui/forms/new、/ui/forms/123、/ui/forms/123/widget/abc)都会进入
✅ 子路由定义:路径必须为相对形式
routes.ts 中的 path 字段不能包含前缀 ui/forms/,否则会形成双重嵌套(如 ui/forms/ui/forms/new),导致匹配失败:
// routes.ts —— 路径均为相对于 "ui/forms/" 的相对路径
export const routes = [
{
path: "new", // → 实际匹配 /ui/forms/new
lazy: () => import('./FormLayoutEditor'),
permission: 'menu_admin',
},
{
path: ":id", // → 实际匹配 /ui/forms/123
lazy: () => import('./FormLayoutEditor'),
permission: 'menu_admin',
},
{
path: ":id/widget/:key", // → 实际匹配 /ui/forms/123/widget/abc
lazy: () => import('./FormWrapperEditor'),
permission: 'menu_admin',
}
];
⚠️ 注意:exact 属性在 v6 中已完全移除,无需设置;lazy 接收的是 () => import(...) 函数(非组件实例),且应直接赋值给 lazy(不是 main)——这是 v6.8+ 支持的动态加载语法。
✅ FormEditor 内部渲染子路由
在
// FormEditor.tsx
import { Routes, Route } from 'react-router-dom';
import { routes } from './routes';
export default function FormEditor() {
return (
<headerlesslayout><routes>
{formData &&
routes.map((r) => (
<route key="{r.path}" path lazy="{r.lazy}" main element></route>
))}
</routes></headerlesslayout>
);
}
? 验证匹配逻辑(关键理解)
| URL | 父路由匹配 | * 捕获内容 | 子路由 path | 是否匹配? | 匹配到的组件 |
|---|---|---|---|---|---|
| /ui/forms/new | ui/forms/* → "new" | "new" | "new" | ✅ | FormLayoutEditor |
| /ui/forms/42 | ui/forms/* → "42" | "42" | ":id" | ✅ | FormLayoutEditor |
| /ui/forms/42/widget/x | ui/forms/* → "42/widget/x" | "42/widget/x" | ":id/widget/:key" | ✅ | FormWrapperEditor |
? 总结要点
- ✅ *父路由必须带 `/`**:启用嵌套路由能力;
- ✅ 子路径必须相对:去掉公共前缀,只保留差异部分;
- ❌ 移除 exact:v6 不再支持该 prop;
- ❌ 不要混用绝对路径:避免 ui/forms/new 在父子两层重复出现;
- ✅ lazy 是函数,不是组件:确保返回 Promise;
- ? 如需权限控制,可在 element 中包裹高阶组件(如
),lazy 仅负责代码分割。
遵循此模式,即可在 React Router 6.9.0 中稳定、可扩展地实现动态子路由渲染。











