Remix v2中Tab路由Outlet内使用可选路由段的问题排查
问题原因与解决方案
你的问题出在路由文件的命名/结构没有建立正确的父子嵌套关系,导致$context.($id).info.tsx这类路由是独立的根级路由,而非staff.tsx的子路由,所以导航时会替换整个页面,而不是渲染到staff.tsx的Outlet中。
为什么原来的方式不行?
Remix v2的文件系统路由约定中,路由的嵌套关系是通过目录层级或者**文件名前缀(父路由在前,用点分隔)**来定义的。你当前的$context.($id).info.tsx是根级路由,对应的路径是/:context(/:id)/info,和staff.tsx对应的/staff是平级路由分支,自然不会嵌套到staff.tsx的Outlet里。
而你测试的staff.profile.tsx能正常工作,是因为这个文件名明确了它是staff.tsx的子路由(前缀staff.),对应路径/staff/profile,符合嵌套规则,所以能渲染到Outlet中。
正确的实现方式
方式1:用目录结构实现嵌套
创建staff目录,将原staff.tsx改为父路由,子路由放在目录内:
- 目录结构:
对应的路由路径:app/routes/ ├── staff/ │ ├── route.tsx # 原staff.tsx内容,作为父路由 │ ├── $context.($id).info.tsx │ └── $context.($id).profile.tsx/staff/:context(/:id)/info/staff/:context(/:id)/profile
方式2:用文件名前缀实现嵌套
直接修改子路由的文件名,添加staff.前缀,明确父子关系:
- 路由文件:
staff.tsx(父路由)staff.$context.($id).info.tsxstaff.$context.($id).profile.tsx
对应的路由路径和方式1一致。
导航链接的注意事项
调整路由结构后,需要修改Tabs的to属性,确保指向正确的子路由路径。比如在staff.tsx中,若已通过useParams获取到context和id,可以这样构造链接:
import { useParams } from "@remix-run/react"; // ... const { context, id } = useParams<{ context: string; id?: string }>(); // ... <Tabs tabs={[ { label: "Info", to: `${context}${id ? `/${id}` : ""}/info` }, { label: "Profile", to: `${context}${id ? `/${id}` : ""}/profile` }, ]} />
这样调整后,导航时子路由就会正确渲染到staff.tsx的Outlet中了。
内容的提问来源于stack exchange,提问作者jckmlczk
相关产品推荐
相关产品推荐

