I want the header to be rendered when on the home page when the user navigates to "/content"
, and when they navigate to "/content/about"
, the About page is rendered without a header. This does not happen. Can you tell me where my problem is?
"/content"
:
Header
Home page by header
"/content/about"
:
About page without header
App.js:
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Content from "./Content";
const ByHeader = () => {
return (
<>
<div>Header</div>
<Content />
</>
);
};
export default function App() {
return (
<Router>
<Switch>
<Route path="/content">
<ByHeader />
</Route>
<Route path="/content/*">
<Content />
</Route>
</Switch>
</Router>
);
}
and
import React from "react";
import { Route } from "react-router-dom";
const Home = () => {
return <div>Home page by header</div>;
};
const About = () => {
return <div>About page without header</div>;
};
const Content = () => {
return (
<>
<Route path="/" exact>
<Home />
</Route>
<Route path="/about" exact>
<About />
</Route>
</>
);
};
export default Content;
The code isn't working right now for a few reasons:
Switch
component.Switch
that renders the header is listed first and once matched, the rest of the routes are ignored, matching or not.Content
component is using absolute paths that don't include the "content"
path segment from the parent route, so these routes are unmatchable.My suggestion would be to treat the content
component more as a layout component that unconditionally renders the header on a route, and renders the route content conditionally within a Switch
component.
Remember that all Route
components alone are inclusively matched and rendered, e.g. anything that matches will be rendered, while Route
components rendered within the Switch
component are exclusively matched and rendered, e.g. the first matching Route
or Redirect
is rendered.
Also keep in mind that when using the Switch
or passing an array of paths to the Route
component that path order and specificity matters. Order the routes/paths in the inverse order of path specificity. For example, "/content/about"
is more specific than "/content"
is more specific than "/"
, so this should be the order of the path when attempting to match.
Here's the implementation of my suggestion.
Example:
const Content = () => {
const { path } = useRouteMatch();
return (
<>
<Route path={[path]} exact component={Header} />
<Switch>
<Route path={`${path}/about`} component={About} />
<Route path={path} component={Home} />
</Switch>
</>
);
};
The parent/App component
<Route path="/content" component={Content} />