无法使用路由器单击 material UI 抽屉组件中的 link
Unable to click a link in material UI drawer component using router
我正在尝试在我的项目中创建抽屉组件。我已经使用了 material UI 中的那个,但是问题是在选择一个选项后我无法将它转到 link 到我的其他页面。在控制台中,我收到以下错误,“未捕获错误:不变性失败:您不应在不变性处使用 <Link> outside a <Router>
”和“上述错误发生在 组件中:”
My front end with the error coming up after pressing an option
我已经在我的 App.js 文件中创建了我的路由器,我认为问题不存在,因为它曾经与我的 bootstrap 导航栏一起使用。
我尝试了一些方法来让它工作,例如添加 onClick: () => history.push('/')
。这对我也不起作用,因为历史是未定义的,即使我这样设置它 const history = useHistory();
.
我也尝试在我的 DrawerComponent class 底部添加 withRouter,但似乎也没有用。
App.js
import React from "react";
import './App.css';
import Home from "./Pages/Home";
import EnglishPremierLeague from "./Pages/EnglishPremierLeague";
import ItalySeriaA from "./Pages/ItalySerieA";
import GermanyBundesliga from "./Pages/GermanyBundesliga";
import FranceLigue1 from "./Pages/FranceLigue1";
import SpainLaLiga from "./Pages/SpainLaLiga";
import WorldCup from "./Pages/WorldCup";
import LeagueStandings from "./Pages/LeagueStandings";
import DrawerComponent from "./components/DrawerComponent";
import {makeStyles} from "@mui/styles";
import { Route, Switch } from 'react-router';
import { BrowserRouter as Router } from 'react-router-dom'
const userStyles = makeStyles({
container: {
display: "flex"
}
})
function App() {
const classes = userStyles();
return (
<div className={classes.container}>
<DrawerComponent/>
<Router>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/EnglishPremierLeague" component={EnglishPremierLeague}/>
<Route path="/ItalySeriaA" component={ItalySeriaA}/>
<Route path="/GermanyBundesliga" component={GermanyBundesliga}/>
<Route path="/FranceLigue1" component={FranceLigue1}/>
<Route path="/SpainLaLiga" component={SpainLaLiga}/>
<Route path="/WorldCup" component={WorldCup}/>
<Route path="/LeagueStandings" component={LeagueStandings}/>
</Switch>
</Router>
</div>
);
}
export default App;
DrawerComponent.jsx
import React from "react";
import {Drawer} from "@mui/material";
import {styled, useTheme} from "@mui/material/styles";
import MuiAppBar from '@mui/material/AppBar';
import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";
import Typography from "@mui/material/Typography";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import Divider from "@mui/material/Divider";
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/MoveToInbox';
import MailIcon from '@mui/icons-material/Mail';
import ListItemIcon from '@mui/material/ListItemIcon';
import {useHistory} from "react-router-dom";
const drawerWidth = 240;
const Main = styled('main', {shouldForwardProp: (prop) => prop !== 'open'})(
({theme, open}) => ({
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerWidth}px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}),
);
const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== 'open',
})(({theme, open}) => ({
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const DrawerHeader = styled('div')(({theme}) => ({
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
}));
const DrawerComponent = () => {
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
const history = useHistory();
console.log(history)
const itemList = [
{
text: "Home",
icon: <InboxIcon/>,
onClick: () => history.push('/')
},
{
text: "English Premier League",
onClick: () => history.push("/EnglishPremierLeague")
},
{
text: "Standings",
icon: <MailIcon/>
},
{
text: "Fixtures"
}
];
return (
<div>
<Box sx={{display: 'flex'}}>
<CssBaseline/>
<AppBar position="fixed" open={open}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{mr: 2, ...(open && {display: 'none'})}}
>
<MenuIcon/>
</IconButton>
<Typography variant="h6" noWrap component="div">
Football Finesse
</Typography>
</Toolbar>
</AppBar>
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon/> : <ChevronRightIcon/>}
</IconButton>
</DrawerHeader>
<Divider/>
<List>
{itemList.map((item, index) => {
const {text, icon, onClick} = item;
return (
<ListItem button key={text} onClick={onClick}>
{icon && <ListItemIcon>
{icon}
</ListItemIcon>}
<ListItemText primary={text}/>
</ListItem>
)
})}
</List>
<Divider/>
</Drawer>
<Main open={open}>
<DrawerHeader/>
</Main>
</Box>
</div>
)
}
export default DrawerComponent;
P.S - 我对反应还很陌生,所以请尽可能简化它,谢谢 :)
您的 <DrawerComponent />
需要在 <Router>
组件内
React Router 的构建方式需要在 Router 组件内部使用许多 React Router 组件。这是因为组件如何相互共享数据
我正在尝试在我的项目中创建抽屉组件。我已经使用了 material UI 中的那个,但是问题是在选择一个选项后我无法将它转到 link 到我的其他页面。在控制台中,我收到以下错误,“未捕获错误:不变性失败:您不应在不变性处使用 <Link> outside a <Router>
”和“上述错误发生在
My front end with the error coming up after pressing an option
我已经在我的 App.js 文件中创建了我的路由器,我认为问题不存在,因为它曾经与我的 bootstrap 导航栏一起使用。
我尝试了一些方法来让它工作,例如添加 onClick: () => history.push('/')
。这对我也不起作用,因为历史是未定义的,即使我这样设置它 const history = useHistory();
.
我也尝试在我的 DrawerComponent class 底部添加 withRouter,但似乎也没有用。
App.js
import React from "react";
import './App.css';
import Home from "./Pages/Home";
import EnglishPremierLeague from "./Pages/EnglishPremierLeague";
import ItalySeriaA from "./Pages/ItalySerieA";
import GermanyBundesliga from "./Pages/GermanyBundesliga";
import FranceLigue1 from "./Pages/FranceLigue1";
import SpainLaLiga from "./Pages/SpainLaLiga";
import WorldCup from "./Pages/WorldCup";
import LeagueStandings from "./Pages/LeagueStandings";
import DrawerComponent from "./components/DrawerComponent";
import {makeStyles} from "@mui/styles";
import { Route, Switch } from 'react-router';
import { BrowserRouter as Router } from 'react-router-dom'
const userStyles = makeStyles({
container: {
display: "flex"
}
})
function App() {
const classes = userStyles();
return (
<div className={classes.container}>
<DrawerComponent/>
<Router>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/EnglishPremierLeague" component={EnglishPremierLeague}/>
<Route path="/ItalySeriaA" component={ItalySeriaA}/>
<Route path="/GermanyBundesliga" component={GermanyBundesliga}/>
<Route path="/FranceLigue1" component={FranceLigue1}/>
<Route path="/SpainLaLiga" component={SpainLaLiga}/>
<Route path="/WorldCup" component={WorldCup}/>
<Route path="/LeagueStandings" component={LeagueStandings}/>
</Switch>
</Router>
</div>
);
}
export default App;
DrawerComponent.jsx
import React from "react";
import {Drawer} from "@mui/material";
import {styled, useTheme} from "@mui/material/styles";
import MuiAppBar from '@mui/material/AppBar';
import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";
import Typography from "@mui/material/Typography";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import Divider from "@mui/material/Divider";
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/MoveToInbox';
import MailIcon from '@mui/icons-material/Mail';
import ListItemIcon from '@mui/material/ListItemIcon';
import {useHistory} from "react-router-dom";
const drawerWidth = 240;
const Main = styled('main', {shouldForwardProp: (prop) => prop !== 'open'})(
({theme, open}) => ({
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerWidth}px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}),
);
const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== 'open',
})(({theme, open}) => ({
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const DrawerHeader = styled('div')(({theme}) => ({
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
}));
const DrawerComponent = () => {
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
const history = useHistory();
console.log(history)
const itemList = [
{
text: "Home",
icon: <InboxIcon/>,
onClick: () => history.push('/')
},
{
text: "English Premier League",
onClick: () => history.push("/EnglishPremierLeague")
},
{
text: "Standings",
icon: <MailIcon/>
},
{
text: "Fixtures"
}
];
return (
<div>
<Box sx={{display: 'flex'}}>
<CssBaseline/>
<AppBar position="fixed" open={open}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{mr: 2, ...(open && {display: 'none'})}}
>
<MenuIcon/>
</IconButton>
<Typography variant="h6" noWrap component="div">
Football Finesse
</Typography>
</Toolbar>
</AppBar>
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon/> : <ChevronRightIcon/>}
</IconButton>
</DrawerHeader>
<Divider/>
<List>
{itemList.map((item, index) => {
const {text, icon, onClick} = item;
return (
<ListItem button key={text} onClick={onClick}>
{icon && <ListItemIcon>
{icon}
</ListItemIcon>}
<ListItemText primary={text}/>
</ListItem>
)
})}
</List>
<Divider/>
</Drawer>
<Main open={open}>
<DrawerHeader/>
</Main>
</Box>
</div>
)
}
export default DrawerComponent;
P.S - 我对反应还很陌生,所以请尽可能简化它,谢谢 :)
您的 <DrawerComponent />
需要在 <Router>
组件内
React Router 的构建方式需要在 Router 组件内部使用许多 React Router 组件。这是因为组件如何相互共享数据