【问题标题】:Making sidebar available for all components | React JS | React Router v6使侧边栏可用于所有组件 |反应 JS |反应路由器 v6
【发布时间】:2022-01-06 14:23:30
【问题描述】:

我正在使用 react router dom v6 并希望实现一个逻辑,其中侧边栏将在我的所有组件中可用。目前,每当我尝试单击侧边栏中的任何内容时,侧边栏都会消失。 我想在我的应用中的所有组件中保留侧边栏。

提供侧边栏

侧边栏不见了

索引.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} 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 />} />
        {/* Sidebar Routes */}
        <Route path="/api/v1/app/userHome" exact element={<Test />} />
        <Route path="/api/v1/app/schedule" exact element={<Scheduler />} />
        <Route path="/api/v1/app/myclassroom" exact element={<Classroom />} />
        <Route
          path="/api/v1/app/myassignments"
          exact
          element={<Assignment />}
        />
        <Route path="/api/v1/app/mymeetings" exact element={<Meeting />} />
        <Route path="/api/v1/app/viewreports" exact element={<ReportCard />} />
      </Routes>
    </Router>,


  document.getElementById('root')
);

Sidebar.js

import {
  ListItemIcon,
  ListItemText,
  List,
  Divider,
  Drawer,
  Avatar,
  Box,
  ListItemButton,
} from "@mui/material";
import { makeStyles } from "@mui/styles";

import HomeIcon from "@mui/icons-material/Home";
import WatchLaterIcon from "@mui/icons-material/WatchLater";
import GroupsIcon from "@mui/icons-material/Groups";
import AssignmentOutlinedIcon from "@mui/icons-material/AssignmentOutlined";
import AssessmentOutlinedIcon from "@mui/icons-material/AssessmentOutlined";
import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined";
import MeetingRoomOutlinedIcon from "@mui/icons-material/MeetingRoomOutlined";

import Logo from "./logo.png";

import { BrowserRouter as Router, Route, Link, Routes } from "react-router-dom";
import Homepage from "../homepage/HomePage";
import Scheduler from "../scheduler/Scheduler";
import Classroom from "../classroom/Classroom";
import Assignment from "../assignment/Assignment";
import ReportCard from "../reportcard/ReportCard";
import Meeting from "../meetings/Meetings";
const drawerWidth = 350;
const useStyles = makeStyles({
  page: {
    background: "#f9f9f9",
    width: "100%",
  },
  root: {
    display: "flex",
  },
  drawer: {
    width: drawerWidth,
  },
  drawerPaper: {
    width: drawerWidth,
    borderRadius: "2%",
  },
  listitem: {
    "&:hover": {
      fontWeight: "fontWeightBold",
      background: "#f9f9f9",
    },
  },
  navlink: {
    textDecoration: "inherit",
    color: "inherit",
  },
});

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>
      <Routes>
      <Route path='/api/v1/app/userHome' element={<Homepage />}></Route>
        <Route path='/api/v1/app/schedule' element={<Scheduler />}></Route>
      </Routes>
    </Box>
  );
}

主页.js

import React from 'react';
import { Grid } from "@mui/material";
import SideMenuBar from '../sidemenubar/SideMenuBar';
import HomePage from '../homepage/HomePage';
import Scheduler from '../scheduler/Scheduler';
import {BrowserRouter as Router, 
    Routes, Route,Navigate,Link} from 'react-router-dom';
class Test extends React.Component{
    render(){
        return (
            <Grid container>
                <Grid item md={4}>
                    <SideMenuBar />
                </Grid>
                
                <Grid item md={8}>
                    <HomePage />
                </Grid>
                
            </Grid>
        )
    }
}

export default Test;

【问题讨论】:

  • 您是说无论当前匹配/渲染的路线如何,您都希望侧边栏渲染?您希望侧边栏在 all 路由上呈现,还是仅在一组特定路由上呈现?在渲染侧边栏时,是否希望所有路由的“页面”组件都渲染到 Grid item md={8} 包装器中?
  • 是的。我实际上希望将侧边栏作为我所有组件和应用程序功能的主要导航器。

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

如果您想在每个路线/页面上呈现侧边栏,那么我建议:

使用 Layout Wrapper 组件和 Outlet

创建一个布局容器组件,将Sidebar 组件和Outlet 呈现到各自的网格列中。渲染嵌套在布局中的页面路由。

import { Outlet } from 'react-router-dom';
import SideMenuBar from '../sidemenubar/SideMenuBar';

const PageLayout = () => (
  <Grid container>
    <Grid item md={4}>
      <SideMenuBar />
    </Grid>    
    <Grid item md={8}>
      <Outlet /> // <-- nested routes rendered here
    </Grid>     
  </Grid>
);

index.js

<Router>
  <Routes>
    <Route path="/" element={<PageLayout />} >
      <Route index element={<Login />} />
      <Route path="/api/v1/app/userHome" element={<UserHome />} />
      <Route path="/api/v1/app/schedule" element={<Scheduler />} />
      <Route path="/api/v1/app/myclassroom" element={<Classroom />} />
      <Route
        path="/api/v1/app/myassignments"
        element={<Assignment />}
      />
      <Route path="/api/v1/app/mymeetings" element={<Meeting />} />
      <Route path="/api/v1/app/viewreports" element={<ReportCard />} />
    </Route>
  </Routes>
</Router>

使用 Wrapper 组件和children Prop

另一种方法是让PageLayout 组件呈现其children,然后包装Routes 组件。

const PageLayout = ({ children }) => (
  <Grid container>
    <Grid item md={4}>
      <SideMenuBar />
    </Grid>    
    <Grid item md={8}>
      {children}
    </Grid>     
  </Grid>
);

index.js

<Router>
  <PageLayout>
    <Routes>
      <Route path="/ element={<Login />} />
      <Route path="/api/v1/app/userHome" element={<UserHome />} />
      <Route path="/api/v1/app/schedule" element={<Scheduler />} />
      <Route path="/api/v1/app/myclassroom" element={<Classroom />} />
      <Route
        path="/api/v1/app/myassignments"
        element={<Assignment />}
      />
      <Route path="/api/v1/app/mymeetings" element={<Meeting />} />
      <Route path="/api/v1/app/viewreports" element={<ReportCard />} />
    </Routes>
  </PageLayout>
</Router>

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2023-03-03
    • 2022-01-11
    • 2022-08-22
    • 2021-12-20
    • 2020-10-04
    • 2018-04-29
    • 2019-06-12
    相关资源
    最近更新 更多