skip to Main Content

I have prepared a simple test case at Github for my question:

screenshot

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 Links in the Drawer, the displayed page stays the Page4 and there is no messages or errors printed in console.

2

Answers


  1. Chosen as BEST ANSWER

    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 the Links in the Drawer.

    Now the app works as intended:

    screenshot


  2. The NavDrawer component is rendering its own BrowserRouter component completely separate from the BrowserRouter that App renders. The links clicked on in NavDrawer are handled by NavDrawer‘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 from NavDrawer and nest NavDrawer under the root BrowserRouter component so the one single router handles all navigation actions.

    export default function NavDrawer() {
      return (
        <Drawer>
          <nav>
            <List>
              {myLinks.map((item, index) => (
                <MyListItem key={index} icon={item.icon} text={item.text} />
              ))}
            </List>
          </nav>
        </Drawer>
      );
    }
    
    <BrowserRouter>
      <NavDrawer /> // <-- rendered within routing context
      <Routes>
        <Route path="page1" element={<Page1 />} />
        <Route path="page2" element={<Page2 />} />
        <Route path="page3" element={<Page3 />} />
        <Route path="*" element={<Page4 />} />
      </Routes>
    </BrowserRouter>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search