Ben Botvinick
Ben Botvinick

Reputation: 3305

Hide header on some pages in react-router-dom

Is there a way I can hide my page header for only some routes in React Router? My issue now is that my App component renders my Main component, which contains my BrowserRouter, and my Header is rendered in my App component, so I have no way of rendering the header based on the route path.

Here's some code:

App.js

import React from 'react';
import {BrowserRouter} from 'react-router-dom';
import Main from './Main';
import Header from './Header';
import Footer from './Footer';

const App = () => (
    <BrowserRouter>
        <Header/>
        <Main/>
        <Footer/>
    </BrowserRouter>
);

export default App;

Main.js

import React from 'react';
import {Route, Switch} from 'react-router-dom';
import Home from './Home';
import Login from './Login';

const Main = () => (
    <main>
        <Switch>
            <Route exact path='/' component={Home}/>
            <Route exact path='/login' component={Login}/>
        </Switch>
    </main>
);

export default Main;

In this application, I would like to hide the header and footer on the login page.

Upvotes: 7

Views: 13285

Answers (6)

Hugh Xu
Hugh Xu

Reputation: 1

Tried to use useEffect to monitor the pathname, but nothing an rerender the page, so it didn't work out. However, I was able to not showing the footer in home Page but others by create another components inside the App.tsx.

import {Footer} from "./components/Footer";

export const ShowFooter = () => {
  const location = useLocation();
  if (location.pathname !== "/") return <Footer />;
  else return <></>;
};
function App() {
  return (
    <>
      <Router>
        <NavBar />
        <Routes>
          <Route path="/" element={<HomePage />} />
        </Routes>
        <ShowFooter />
      </Router>
    </>
  );
}

export default App;

Upvotes: 0

mohammadZ
mohammadZ

Reputation: 21

in react-router-dom v6 there is a hook useLocation that gets the url as it changes using it is 100% helpful and solves this issue.

function App () {
let location = useLocation();
      return (
           <BrowserRouter>
                {location.pathname === '/login' && location.pathname==='/signup' && <Header/>}
                <Switch>
                    <Route exact path='/' component={Home}/>
                    <Route exact path='/login' component={Login}/>
                    <Route exact path='/signup' component={Signup}/>
                </Switch>
                {location.pathname === '/login' && location.pathname==='/signup' && <Footer/>}
            </BrowserRouter>
        );
    }
}

Upvotes: 2

Jean Ntagengwa
Jean Ntagengwa

Reputation: 11

This worked for me:

props kept coming back undefined in my class component

{window.location.pathname !== "/app" ? (
          <NavBar />
) : null}

Upvotes: 1

scuzzd
scuzzd

Reputation: 1

You could do something like this:

<Switch>
          {authRoutes.map(({ path, component: C }) => (
            <Route
              key={`${C}-route`}
              path={path}
              render={(props) => (
                <div className="app__activePage">
                  <C {...props} />
                </div>
              )}
            ></Route>
          ))}

          {routes.map(({ path, component: C }) => (
            <Route
              key={`${C}-route`}
              path={path}
              render={(props) => (
                <div className="app__activePage">
                  <Header />
                  <C {...props} />
                </div>
              )}
            ></Route>
          ))}
</Switch>

I usually define all of my routes in another file and export them by group. This allows me to:

  1. Define all of the routing in one place
  2. Handle different routing groups more cleanly

Upvotes: 0

Sanaullah
Sanaullah

Reputation: 374

You can use withRouter Higher-Order component to access props.location object in your App component and check if a user is on login or signup page using props.location.pathname

import {BrowserRouter, withRouter} from 'react-router-dom'
const App = () => (
   <BrowserRouter>

     {
      props.location.pathname!=='/login' ? <Header/>:null
     }
        <Main/>
        <Footer/>

   </BrowserRouter>
);

export default withRouter(App);

Upvotes: 6

Ben Botvinick
Ben Botvinick

Reputation: 3305

I ended up using Redux. This was the best option because I have over twenty pages (only 3 shown in code below) on all of which the visibility of the header/footer vary. I created one reducer for the header and one for the footer. Here was my solution:

import ...

class App extends React.Component {
    render() {
        return (
            <BrowserRouter>
                {this.props.header ? <Header/> : ''}
                <Switch>
                    <Route exact path='/' component={Home}/>
                    <Route exact path='/login' component={Login}/>
                    <Route exact path='/signup' component={Signup}/>
                </Switch>
                {this.props.footer ? <Footer/> : ''}
            </BrowserRouter>
        );
    }
}

const mapStateToProps = state => state;
export default connect(mapStateToProps)(App);

Upvotes: 4

Related Questions