Ali
Ali

Reputation: 1225

Render components for all routes except one specific route

I am writing a React app with multiple routes, I have header and footer components as well which will be visible on all components. But now I want to hide footer component for a specific route.

<Header />
        <Switch>
          <Route path={routes.home} exact component={Home} />
          <Route path={routes.office} component={Office} />
          <Route path={routes.park} exact component={Park} />
          ...
          ...
          ...
          <Route path={routes.shopping} component={Shopping} />
        </Switch>
    <Footer />

so header and footer component are always rendered. But now I want footer component visible for all routes except shopping, how can I do that?

Upvotes: 2

Views: 1988

Answers (2)

Lev Popov
Lev Popov

Reputation: 21

The best way to do this without using render props or the useRouteMatch hook is to use one specific route for the page where you don't want the header or footer, and a "catch-all" route that will match all other routes. You can then use a nested Switch statement to handle the rest of your applications routes.

In the example below I have a '/auth' route which will only render the Auth component and nothing else. In the rest of the application (after the user had logged in) I want the Navbar and Sidebar components to show up on all routes, so they live inside the 'catch-all' Route which does not have a 'path' property set. This means it will trigger for all routes except '/auth' (because /auth is declared before it).

<Router>
  <div className="App">
    <Switch>
      {/* The route which will not render the sidebar and navbar components */}
      <Route path="/auth">
        <Auth/>
      </Route>
      {/* Catch-all route that will match everything except /auth and render Sidebar and Navbar on all pages */}
      <Route>
        <Sidebar/>
        <Navbar/>
        {/* The rest of the routes for the application */}
        <Switch>
          <Route exact path="/">
            <Home/>
          </Route>
          <Route path="/about">
            <About/>
          </Route>
          <Route path="/projects">
            <Projects/>
          </Route>
        </Switch>
      </Route>
    </Switch>
  </div>
</Router>

Upvotes: 2

Willman.Codes
Willman.Codes

Reputation: 1413

There are a few ways to accomplish this, one way would be:

First pass the routes you want to hide via props as an array:

<Router>
    <Header hideRoutes={[routes.shopping]} />
    <Switch>
        <Route path={routes.home} exact component={Home} />
        <Route path={routes.office} component={Office} />
        <Route path={routes.park} exact component={Park} />
        {/*moreRoutes*/}
        <Route path={routes.shopping} component={Shopping} />
    </Switch>
    <Footer hideRoutes={[routes.shopping]} />
</Router>

Then in your Header and Footer components check the pathname for the hide route and then hide when appropriate by passing back an empty div

const Header = (props)=>{
    const {hideRoutes , location:{pathname}} = props
    let shouldHide = false
    hideRoutes.some(hideRoute => {
        if (pathname === hideRoute)
            return shouldHide = true
    })
    if (shouldHide) 
        return <div/>

    //proceed to return header
}

Upvotes: 0

Related Questions