1

I have 2 types of routes, one is like website/app level and one is SideMenu level, which is kind of nested routes. My problem is to change content by clicking on a menu-item of the SideMenu. Somehow I'm not able to get this work correctly. One important note, I use react-router-dom v6!

In my app I have the following:

function App(props) {
    return (
        <BrowserRouter>
            <Routes>
                <Route exact path="/" element={<MainApp {...props} />}></Route>
                <Route path="/signin" element={<SignIn />}></Route>
                <Route path="/register" element={<SignUp />}></Route>
                <Route path="*" element={<PageNotFound />}></Route>
            </Routes>
        </BrowserRouter>
    );
}

In the MainApp I have the following:

export default function MainApp(props) {
    const { classes } = props;

    return (
        <div className={classes.root}>
            <AppBar classes={classes} />
            <SideMenu classes={classes} />
            <main className={classes.appContent}>
                <Routes>
                    <Route path="dashboard" render={() => <Dashboard />} />
                    <Route path="checkout" render={() => <Checkout />} />
                    <Route path="users" render={() => <Users />} />
                </Routes>
            </main>
        </div>
    );
}

My SideMenu looks like this:

const SideMenu = ({ classes }) => {
    return (
        <Drawer
            variant="permanent"
            className={classes.drawer}
            classes={{ paper: classes.drawerPaper }}
        >
            <NavItems />
        </Drawer>
    );
};

Finally the ListItems, which are menu items of the SideMenu:

function NavItems(props) {
    return (
        <div>
            <List>
                {MenuItemsData.map((item) => {
                    return (
                        <ListItem
                            button
                            key={item.id}
                            to={item.url}
                            component={Navigate}
                        >
                            <ListItemIcon>{item.icon()}</ListItemIcon>
                            <ListItemText primary={item.title} />
                        </ListItem>
                    );
                })}
            </List>
        </div>
    );
}

I do got it working using props drilling by passing a handle click to a list item. But I like Routers more as it's cleaner and easier to understand.

So my question is, how do I get navigating content working using SideMenu with Router within a Router?

AndaluZ
  • 1,410
  • 3
  • 15
  • 33
  • 1
    You can't put routers inside other routers. All the `Route` components in `MainApp` are incorrectly using a `render` prop which doesn't exist in RRDv6. Also, shouldn't the `component` prop of the `ListItem` be a `Link` or `NavLink` instead of the `Navigate` component? I don't see how that could possibly work. – Drew Reese Dec 21 '21 at 19:38
  • If nested routers is not possible, how to change content in main using SideMenu without passing handleClick-callback to props and drill it down to a ListItem (of the SideMenu)? I thought Link was from RRD v5, so I used v6's Navigate. I'm kind of new to RRD and MUI's Drawer. – AndaluZ Dec 22 '21 at 10:05
  • 1
    What callback props are you passing down to anything? The `Link` and `NavLink` are still available in RRDv6. The `Navigate` effectively replaced the `Redirect` component from v5. – Drew Reese Dec 22 '21 at 21:55
  • 1
    I passed down handleClick function to ListItem to perform content change, but then want to replace this pattern by Routers because it's cleaner and easier to understand by other developers. I fixed the problem, see my own answer. – AndaluZ Dec 23 '21 at 10:36

1 Answers1

1

I found the solution thanks to this blog post: https://www.codingdeft.com/posts/react-router-tutorial/

In my app function, I replaced the root "/" to:

<Route path="main/*" element={<MainApp {...props} />}></Route>

In MainApp I modified the nested routes (which is allowed) to:

<Routes>
    <Route path="dashboard" element={<Dashboard />}></Route>
    <Route path="checkout" element={<Checkout />}></Route>
    <Route path="users" element={<Users />}></Route>
</Routes>

thnx to the comment of Drew Reese.

Finally in ListItems I have this:

<ListItem button key={item.id} to={item.url} component={NavLink}>
    <ListItemIcon>{item.icon()}</ListItemIcon>
    <ListItemText primary={item.title} />
</ListItem>

Where item.url could be "dashboard", "checkout" or "users".

AndaluZ
  • 1,410
  • 3
  • 15
  • 33