I have prepared a simple test case at Github for my question:
In my App.jsx there is following code:
<NavDrawer />
<BrowserRouter>
<Routes>
<Route path="page1" element={<Page1 />} />
<Route path="page2" element={<Page2 />} />
<Route path="page3" element={<Page3 />} />
<Route path="*" element={<Page4 />} />
</Routes>
</BrowserRouter>
And in the NavDrawer.jsx I have the code:
const drawerLinks = [
{ text: "Page 1", path: "/page1", icon: <CarCrash /> },
{ text: "Page 2", path: "/page2", icon: <Help /> },
{ text: "Page 3", path: "/page3", icon: <Directions /> },
{ text: "Page 4", path: "/page4", icon: <CarRepair /> },
];
function MyListItem({ text, path, icon }) {
return (
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>{icon}</ListItemIcon>
<Link to={path}>
<ListItemText primary={text} />
</Link>
</ListItemButton>
</ListItem>
);
}
export default function NavDrawer() {
return (
<Drawer>
<BrowserRouter>
<nav>
<List>
{drawerLinks.map((item, index) => (
<MyListItem key={index} icon={item.icon} text={item.text} />
))}
</List>
</nav>
</BrowserRouter>
</Drawer>
);
}
Unfortunately, nothing happens when I click one of the Link
s in the Drawer
, the displayed page stays the Page4
and there is no messages or errors printed in console.
2
Answers
I've received a friendly answer by ulvesked at Reddit -
I have to use not two, but a single
BrowserRouter
at the top App.jsx file.Also, I missed to pass the
path
argument to theLink
s in theDrawer
.Now the app works as intended:
The
NavDrawer
component is rendering its ownBrowserRouter
component completely separate from theBrowserRouter
thatApp
renders. The links clicked on inNavDrawer
are handled byNavDrawer
‘s router and the other main router is completely unaware of any navigation actions that were effected and handled.You need only one router per application, generally at or near the root level of the app.
Remove
BrowserRouter
fromNavDrawer
and nestNavDrawer
under the rootBrowserRouter
component so the one single router handles all navigation actions.