'Unable to click a link in material UI drawer component using router
I am trying to create a drawer component in my project. I have used the one from material UI however the problem is I cannot get it to link to my other pages after selecting an option. In the console I get the following errors, "Uncaught Error: Invariant failed: You should not use <Link> outside a <Router>
at invariant" and "The above error occurred in the <Router.Consumer> component:"
My front end with the error coming up after pressing an option
I have created my router in my App.js file and I dont think the problem is there as it used to work with my bootstrap navigation bar.
I have tried a few things on trying to get this to work such as adding onClick: () => history.push('/')
. This also didn't work for me as the history was undefined even though I set it like so const history = useHistory();
.
I have also tried adding in the withRouter at the bottom of my DrawerComponent class and that didn't seem to work either.
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 - I am very new to react so please dumb it down as much as possible, thank you :)
Solution 1:[1]
Your <DrawerComponent />
needs to be inside the <Router>
component
React Router is built in a way that requires many React Router component to be used inside of a Router component. This is because of how the components share data to each other
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | gear4 |