react-router-dom中Navigate组件的to属性是否支持二级路由跳转?
当然支持二级路由跳转啦,你的问题不是Navigate不支持二级路径,而是嵌套路由的使用方式错了,没用到<Outlet />组件来渲染子路由内容,导致LoginForm没地方显示~
分析你的原始代码问题
你最初的App.jsx里把/otAndTO/login设为/otAndTO的子路由,这本身没问题,但作为父路由element的OTAndTOGateKeeper犯了两个关键错误:
- 它没有返回
<Outlet />组件:嵌套路由的父组件必须用<Outlet />来承载子路由的内容,不然子路由的组件(比如LoginForm)根本没地方渲染; - 重定向逻辑和嵌套路由冲突:当你访问
/otAndTO时,GateKeeper会跳转到/otAndTO/login,但此时路由切换到子路由后,父组件还是GateKeeper,它又会检查token(依然没有),再次跳转到/otAndTO/login,相当于陷入了隐性的重定向循环,同时因为GateKeeper没渲染Outlet,LoginForm也没法显示,所以页面空白。
而你修改后的写法能生效,是因为把/login改成了顶层路由——Navigate到/login时,路由直接匹配到顶层的LoginForm组件,不需要依赖父路由的Outlet,所以能正常显示,但这相当于放弃了嵌套路由的结构,路由层级不够清晰(/login和/otAndTO平级,其实它应该属于/otAndTO的子路由)。
正确解决方案(保留嵌套路由结构)
只需要修改OTAndTOGateKeeper.jsx,引入Outlet组件实现嵌套路由的权限控制,同时调整重定向逻辑:
import { Navigate, Outlet } from 'react-router-dom'; export default function OTAndTOGateKeeper(){ const hasToken = sessionStorage.getItem("accessToken"); if (hasToken) { // 有token,允许访问子路由,用Outlet渲染子路由内容 return <Outlet />; } else { // 无token,跳转到当前父路由下的login子路由(用相对路径更灵活) return <Navigate to="login" replace />; } }
App.jsx保持原来的嵌套路由结构即可:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import OTAndTOGateKeeper from "./components/otAndTO/OTAndTOGateKeeper.jsx"; import OTAndTOForm from "./components/otAndTO/OTAndTOForm.jsx"; import LoginForm from "./components/otAndTO/LoginForm.jsx"; return ( <Router> <Routes> <Route path='/otAndTO' element={<OTAndTOGateKeeper/>}> <Route index element={<OTAndTOForm/>}/> <Route path="login" element={<LoginForm/>}/> </Route> </Routes> </Router> );
这个方案的优势
- 保持了嵌套路由的结构,路由层级更清晰(
/otAndTO/login明确属于/otAndTO的子功能); - 权限控制更合理:GateKeeper只负责判断是否允许访问子路由,具体子路由内容由Outlet渲染;
- 用相对路径
to="login"比绝对路径/otAndTO/login更灵活,万一以后父路由路径修改,不需要同步调整重定向地址。
总结一下:Navigate完全支持二级路由跳转,你的问题核心是没正确使用嵌套路由的<Outlet />组件,补上Outlet后,嵌套路由的权限控制就能正常工作啦~
备注:内容来源于stack exchange,提问作者The KNVB
相关产品推荐
相关产品推荐

