I have HTML structure like this:
<body>
<nav>
<!--navigation elements -->
</nav>
<div className='main'>
<!--other elements -->
</div>
<div className='container'></div>
</body>
And routing defined like this:
<Router>
<Fragment>
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Alert />
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
</Switch>
</div>
</Fragment>
</Router>
The "container" element is present on all routes however I do not want it to be rendered on the "/" route.
How can I stop <div className="container">
from being rendered on the "/"
route? I want it to be rendered on all other routes except of "/"
.
A solution I found, but don't want to use is to explicitly insert the element with class="container"
in each component that is rendered in my <Switch>
. Is there a better way?
The Route component from react-router is public by default but we can build upon it to make it restricted. We can add a restricted prop with a default value of false and use the condition if the user is authenticated and the route is restricted, then we redirect the user back to the Dashboard component.
1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.
You should be able to achieve what you require via nested routes and a "no match route".
The idea would be to introduce structure to your routing via nested routes, to restrict rendering of <div className="container">
to non /
routes.
To do this, you could extract a component (ie WithContainer
) that renders a <Route>
for paths; /register
, /login
and /profiles
, inside of the <div className="container">
. You would then change your <Switch>
to now render two routes for the following route cases;
<Route/>
that renders the Landing
component on an exact match of /
<Route/>
that renders your new WithContainer
component on no specific route (ie any path that does not exactly match /
)By using the <Switch>
in this way, it causes the routing behaviour to render either Landing
or WithContainer
(but not both) depending on the first matched route. We take advantage of that behaviour to restrict rendering of the WithContainer
(and in turn, the <div className="container">
element) for "non /
" routes.
In code, this approach could be expressed as:
const WithContainer = () => (
<div className="container">
{ /* Wrap routes in container div */ }
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
</div>)
const Main = () => (
<main>
<Switch>
<Route exact path='/' component={Landing}/>
<Route component={ WithContainer } /> {/* No match route */ }
</Switch>
</main>
)
Hope that helps!
With the latest version of React Router, you can provide an array of strings for the path
prop so that a specific route renders on multiple matches:
<Route path={['/one', '/two', '/three']} component={SomeComponent} />
Here's a link to the relevant documentation: https://reacttraining.com/react-router/web/api/Route/path-string-string.
If you don't want to create a separate component, you can just do this. You need to keep the inner switch as well, if you want to keep the original functionality.
// parent switch
<Switch>
<Route exact path="/" component={Landing} />
// start route wrap!!!
<Route>
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
</Switch>
</div>
</Route>
// end route wrap!!!
</Switch>
You should think of Routes as of any other UI components. You can nest them arbitrarily.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With