I'm trying to implement nested routing in my react app The routes in my root app.jsx file are defined like this.
<>
<Router>
<DrawerContextProvider>
<Appbar />
<Switch>
<Route exact path='/admin'>
<Admin/>
</Route>
<Route path='/technician' component={Technician} />
<Route path='/accountmanager' component={AccountManager} />
</Switch>
</DrawerContextProvider>
</Router>
</>
This is the code in my admin component
function Admin() {
const classes = useStyles();
const { open } = useContext(DrawerContext)
const { url, path } = useRouteMatch();
return (
<>
<SideMenu iconsandnames={iconsandnames} />
<div>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
<Switch>
<Route exact path={path} >
<Dashboard />
</Route>
<Route path={`${path}/:id`} >
<Outlet />
</Route>
</Switch>
</main>
</div>
</>
)
}
function Outlet() {
const { id } = useParams();
console.log(id);
return (
<div>
<h3>{id}</h3>
</div>
);
}
This is the code in my Side menu component
export default function MiniDrawer({ iconsandnames }, props) {
const classes = useStyles();
const theme = useTheme();
const { url, path } = useRouteMatch();
const { open, handleDrawerClose } = useContext(DrawerContext)
return (
<div >
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<div className={classes.toolbar}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<Divider />
<List>
{iconsandnames.map((data) => (
data.text == "Home" ? (
<Link to={url}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>):
( <Link to={`${url}/${data.route}`}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>)
))}
</List>
</Drawer>
</div>
);
}
this is the iconsandnames array I'm passing into the sidemenu
const iconsandnames = [
{
iconname: 'home',
text: 'Home',
route: 'home'
},
{
iconname: 'rounded_corner',
text: 'Projects',
route: 'projects'
},
{
iconname: 'account_box',
text: 'Account managers',
route: 'accountmanagers'
},
{
iconname: 'build',
text: 'Contractors',
route: 'contractors'
},
{
iconname: 'perm_identity',
text: 'Clients',
route: 'clients'
},
{
iconname: 'work_outline',
text: 'Work Orders',
route: 'workorders'
},
{
iconname: 'preview',
text: 'Additional',
route: 'additional'
},
]
http://localhost:3000/admin shows me

http://localhost:3000/admin/projects shows me

ideally the sidemenu should not disappear when I switch the route but instead it is disappearing over here. Any ideas on what might be the problem and how can I solve it?
Issue
You are specifying the
exactprop on the "/admin" path, so any nested routes can no longer be matched and rendered.Admin
Solution
When rendering
Routecomponents into aSwitch, path order and specificity matter. You will want to order your paths from more specific to less specific, in order to give the more specific paths a chance to be matched and rendered first before less specific paths.Routes - remove the
exactprop from the "/admin" route so any nested route can be matched.Admin - reorder the routes by specificity.