React router dom V6渲染空白页 报Navbar非Route组件错误
问题原因
React Router DOM V6 强制要求:<Routes> 组件的直接子元素只能是 <Route> 组件,或仅包裹 <Route> 组件的 <React.Fragment>。
你的代码存在两个不符合规则的写法:
- 直接把
<Navbar />、<Container />这类非路由组件放到了<Routes>直接子级 - 把多个业务路由
<Route>作为<Container>组件的子元素,而非嵌套在父级<Route>下
这就是报错的直接来源。你之前用Fragment包裹无效,本质是因为包裹的内容里仍然混有非Route组件,用法不符合规则,路由解析失败直接导致页面白屏。
修复方案
V6 实现「导航栏、侧边栏常驻,仅内容区随路由切换」的布局,正确用法是布局路由 + <Outlet /> 占位,步骤如下:
- 抽离公共布局组件,在需要渲染子路由内容的位置插入
<Outlet />作为内容占位符 - 新增一个不指定path(或指定根路径)的布局Route,把公共布局组件传入它的
element属性 - 所有需要套用该布局的业务路由,全部作为布局Route的子路由配置
- 不需要套用布局的页面(比如你的登录页),和布局Route平级放置即可
修复后的完整代码参考:
import { BrowserRouter as Router, Routes, Route, Outlet } from 'react-router-dom'; // 抽离全局公共布局 const AppLayout = () => { return ( <> <Navbar /> <Container> <SideBar /> {/* Outlet为子路由页面的渲染出口,不要遗漏 */} <div className="main-content"> <Outlet /> </div> </Container> </> ) } function App() { const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; const isAdmin = JSON.parse( JSON.parse(localStorage.getItem("persist:root") || "{}").user ).currentUser.isAdmin; return ( <Router> <Routes> {/* 无需公共布局的路由单独平级放置 */} <Route path="/login" element={<Login />} /> {/* 公共布局路由 */} <Route element={<AppLayout />}> {/* 以下路由都会自动带上Navbar、SideBar布局 */} <Route path="/" element={<Home />} /> <Route path="/users" element={<UserList />} /> <Route path="/user/:id" element={<User />} /> <Route path="/Products" element={<ProductsList />} /> <Route path="/Product/:id" element={<Product />} /> <Route path="/addProduct" element={<AddProduct />} /> </Route> </Routes> </Router> ); }
额外说明
- 如果你需要登录页也显示导航、侧边栏,直接把
/login对应的Route移到布局Route的子路由列表中即可 - 你代码中读取的
isAdmin权限判断逻辑,可以直接放在布局组件、或对应路由的element组件中做路由拦截,不需要改动现有路由结构 - 支持多层嵌套路由,每一层父路由对应的组件中,只需要在对应位置放
<Outlet />,就能渲染下一层子路由的内容
内容的提问来源于stack exchange,提问作者Wesle6
相关产品推荐
相关产品推荐

