Reputation: 527
I can't seem to figure out what I'm doing wrong. Basically I have an admin header that navigates to /admin. There I want to have a link to travel to /admin/render and display a component there. However, nothing displays at /admin/render. What am I missing?
https://codesandbox.io/s/react-router-nesting-forked-zxp7w?file=/index.js:0-1807
import ReactDOM from "react-dom";
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
import {
Grid,
AppBar,
Container,
IconButton,
List,
ListItem,
ListItemText,
Toolbar
} from "@material-ui/core";
ReactDOM.render(<NestingExample />, document.getElementById("root"));
export function NestingExample() {
return (
<Router>
<div>
<Grid container>
<Grid item xs={12}>
<List>
<ListItem component={Link} to="/admin">
<ListItemText primary="Admin" />
</ListItem>
</List>
</Grid>
</Grid>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/admin" component={AdminLanding} />
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
function AdminLanding() {
let { path, url } = useRouteMatch();
return (
<Grid container>
<Link to={`${url}/rendering`}>Rendering with React</Link>
<Switch>
<Route exact path={path}>
<h3>Please select a topic.</h3>
</Route>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
</Switch>
</Grid>
);
}
function Topic() {
let { topicId } = useParams();
return (
<div>
<h3>{topicId}</h3>
</div>
);
}
Upvotes: 1
Views: 301
Reputation: 202721
The root route rendering your admin landing page is only rendered when the path is exactly "/admin".
<Route exact path="/admin" component={AdminLanding} />
Sub-routes will be excluded and not matched by the nested Switch
since AdminLanding
is no longer rendered.
Remove the exact
prop so the nested Switch
handles matching nested pages.
<Route path="/admin" component={AdminLanding} />
I suggest also inverting the order (or listing more specific paths before less specific paths) of the nested routes so they also don't need the exact
prop.
<Switch>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
<Route path={path}>
<h3>Please select a topic.</h3>
</Route>
</Switch>
Note: It also seems that you really want the nested header to always be rendered since it will only render the h3
when not matched by any other path. Maybe this is just a simplified code example though. If not then it should probably be pulled and rendered before the Switch
.
Upvotes: 2