React Router v6根路径/路由无内容渲染 其余路由正常问题排查
问题原因
React Router v6 嵌套路由匹配规则和旧版本差异导致的问题:
- 当父级路由路径为
/时,嵌套子路由如果配置path: '/',会被识别为绝对路径路由,不会作为父路由的默认索引子路由渲染到<Outlet />位置 - 访问根路径
/时,框架只能匹配到外层的Layout组件,但是Layout内的Outlet找不到可匹配的子路由元素,因此Home组件不会渲染,页面显示空白 - 你之前手动额外添加一层
<Route path='/' element={<Home />} />的写法,本质是重复声明了同路径路由,虽然能临时解决渲染问题,但逻辑冗余,违背了统一路由配置的设计初衷。 - 原有配置还有一个隐藏bug:受保护的
/signup路由父级写死path='/'、子级写绝对路径/signup,会导致访问时直接跳过ProtectedRoute鉴权逻辑,未登录状态也能访问页面。
修复方案
不需要冗余声明路由,只需要按照v6的路由规则调整配置即可,所有路由仍然统一维护在独立配置文件中:
- 首先调整路由配置文件
routes.js,用index属性标记根路由为索引路由,嵌套路由改用相对路径:
import React from 'react'; import Home from '../pages/home'; import Login from '../pages/login'; import ProtectedPage from '../pages/protected'; import Signup from '../pages/signup'; export const appRoutes = [ { id: 'SOME_UNIQUE_STRING', path: 'protected', // 嵌套路由去掉开头/,使用相对路径自动拼接父级路径 protected: true, element: <ProtectedPage />, }, { id: 'Home', index: true, // 替换原path:'/',标记为父路由/的默认索引路由 protected: false, element: <Home />, }, ]; export const routesWithoutLayout = [ { id: 'Signup', path: 'signup', // 嵌套受保护路由使用相对路径 protected: true, element: <Signup />, }, { id: 'Login', path: '/login', // 非嵌套路由可直接写绝对路径 protected: false, element: <Login />, }, ];
- 调整
NavigationRoutes.js的路由渲染逻辑,支持识别index路由,修正受保护路由的路径匹配逻辑:
import React from 'react'; import { Routes, Route } from 'react-router-dom'; import Layout from '../components/Layout/Layout'; import ProtectedRoute from './privateRoute'; import { appRoutes, routesWithoutLayout } from './routes'; const NavigationRoutes = () => ( <Routes> {/* 渲染不需要通用布局的路由 */} {routesWithoutLayout.map(({ protected: _protected, id, path, index, element }) => _protected ? ( <Route key={id} path={path} element={<ProtectedRoute />}> <Route index element={element} /> </Route> ) : ( <Route key={id} path={path} index={index} element={element} /> ) )} {/* 渲染带通用布局的路由 */} <Route path='/' element={<Layout />}> {appRoutes.map(({ protected: _protected, id, path, index, element }) => _protected ? ( <Route key={id} path={path} element={<ProtectedRoute />}> <Route index element={element} /> </Route> ) : ( <Route key={id} path={path} index={index} element={element} /> ) )} </Route> <Route path='*' element={<p>Page not found</p>} /> </Routes> ); export default NavigationRoutes;
方案说明
- 用
index: true标记的路由,会在父路由路径完全匹配时自动渲染到对应Outlet位置,不需要重复书写路径,彻底避免冗余路由声明 - 嵌套路由统一使用不带开头
/的相对路径,React Router v6会自动完成路径拼接,同时修复了原有受保护路由鉴权失效的隐藏问题 - 所有路由配置仍然统一维护在独立的
routes.js文件中,不需要在导航组件内硬编码单独的路由项,完全符合最初的设计逻辑。 - 原有
ProtectedRoute、Layout、入口文件的代码不需要做任何修改。
内容的提问来源于stack exchange,提问作者Sandip Dhang
相关产品推荐
相关产品推荐

