使用React Router DOM v6如何让侧边栏在所有组件中全局显示
故障原因
- 路由配置结构错误:当前只有
/api/v1/app/userHome路径渲染的Test组件包含侧边栏,其他业务路径(比如/api/v1/app/schedule)直接渲染对应业务组件,没有嵌套侧边栏布局,跳转后自然不会显示侧边栏 - 冗余逻辑冲突:SideMenuBar内部定义了一套Routes路由规则,和全局路由重复,会导致路由匹配混乱
- 没有使用React Router v6的嵌套路由能力实现公共布局复用,这是实现全局固定侧边栏的标准方案
修复步骤
1. 调整全局路由配置(index.js)
将所有需要显示侧边栏的路由,全部嵌套到公共布局路由下,修改后的代码如下:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import {BrowserRouter as Router, Routes, Route, Navigate, Link, Outlet} from 'react-router-dom'; import Login from '../src/components/Login/LoginPage'; import Test from '../src/components/test/Test'; import Homepage from '../src/components/homepage/HomePage'; import Scheduler from '../src/components/scheduler/Scheduler'; import Classroom from '../src/components/classroom/Classroom'; import Assignment from '../src/components/assignment/Assignment'; import Meeting from '../src/components/meetings/Meetings'; import ReportCard from '../src/components/reportcard/ReportCard'; import SideMenuBar from '../src/components/sidemenubar/SideMenuBar'; ReactDOM.render( <Router> <Routes> <Route path='/' element={<Login />} /> <Route path='/api/v1/testpath' element={<Test />} /> {/* 公共布局路由:所有子路由都会共享侧边栏 */} <Route path="/api/v1/app" element={<Test />}> <Route path="userHome" element={<Homepage />} /> <Route path="schedule" element={<Scheduler />} /> <Route path="myclassroom" element={<Classroom />} /> <Route path="myassignments" element={<Assignment />} /> <Route path="mymeetings" element={<Meeting />} /> <Route path="viewreports" element={<ReportCard />} /> </Route> </Routes> </Router>, document.getElementById('root') );
2. 修改公共布局组件(即你定义的Test组件,对应HomePage.js文件)
将原来固定渲染的<HomePage />替换为路由出口<Outlet />,子路由匹配到的内容会自动渲染在这个位置,修改后的代码如下:
import React from 'react'; import { Grid } from "@mui/material"; import SideMenuBar from '../sidemenubar/SideMenuBar'; import { Outlet } from 'react-router-dom'; class Test extends React.Component{ render(){ return ( <Grid container> <Grid item md={4}> <SideMenuBar /> </Grid> <Grid item md={8}> {/* 子路由内容渲染出口 */} <Outlet /> </Grid> </Grid> ) } } export default Test;
3. 清理SideMenuBar组件冗余逻辑
删除SideMenuBar内部的<Routes>和对应的<Route>定义,这部分逻辑已经由全局嵌套路由处理,仅保留侧边栏菜单和跳转逻辑即可,修改后的核心返回结构如下:
// 其他导入代码保留不变,仅修改return部分 export default function Sidemenubar() { const classes = useStyles(); return ( <Box sx={{ display: "flex" }}> <Divider /> <Drawer className={classes.drawer} variant="permanent" classes={{ paper: classes.drawerPaper }} anchor="left" > {/*App Logo */} <Avatar src={Logo} alt="404" sx={{ width: 100, height: 100, alignSelf: "center", margin: 1 }} /> {/*Menu Items */} <List component="nav"> <Link to="/api/v1/app/userHome" className={classes.navlink}> <ListItemButton sx={{ "&:hover": { fontWeight: "bold", boxShadow: 1, background: "#6D62DA", }, }} > <ListItemIcon> <HomeIcon /> </ListItemIcon> <ListItemText primary="Home" /> </ListItemButton> </Link> <Divider /> <Link to="/api/v1/app/schedule" className={classes.navlink}> <ListItemButton sx={{ "&:hover": { fontWeight: "bold", boxShadow: 1, background: "#6D62DA", }, }} > <ListItemIcon> <WatchLaterIcon /> </ListItemIcon> <ListItemText primary="Scheduler" /> </ListItemButton> </Link> <Divider /> {/* 其他菜单项逻辑不变 */} </List> </Drawer> </Box> ); }
修改完成后,所有/api/v1/app/*路径下的页面都会固定显示侧边栏,仅右侧内容区域会根据路由切换。
内容的提问来源于stack exchange,提问作者Subhodeep bhowmick
相关产品推荐
相关产品推荐

