简体   繁体   中英

How to skip header and footer for certain routes in ReactJS?

I have the following code which renders an app with a header and footer for all pages.

app.js

import React from 'react';
import {
  Route,
  Switch
} from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router'
import Layout from './components/Layout'
import Home from './homeComponent';
import Login from './loginComponent';
import Dashboard from './dashboardComponent';

const App = ({ history }) => {
  return (
    <Layout>
        <ConnectedRouter history={history}>
            <Switch>
              <Route exact={true} path="/" component={Home} />
              <Route path="/login" component={Login} />
              <Route path="/dashboard" component={Dashboard} />
              ... more routes
              <Route component={NoMatch} />
            </Switch>
        </ConnectedRouter>
    </Layout>
  );
};

export default App;

layout.js

import Header from './headerComponent'
import Footer from './footerComponent'
import React, {Component} from 'react'

class Layout extends Component {
    render() {
        return (
            <div>
                <Header />
                {this.props.children}
                <Footer />
            </div>
        )
    }
}

What is the best way to skip rendering of the header and footer for certain pages like Home and Login routes?

I'd recommend creating two layouts with their own header and footers and a private route:

Public Layout

export const PublicLayout = (props) => <div>
<PublicHeader/>
  <Switch>
    <Route exact path="/" component={HomePage}/>
    <Route exact path='/signin' component={SigninForm} />
    <Route exact path='/signup' component={Signup} />         
  </Switch>
<PublicFooter/>

Protected Layout

export const ProtectedLayout = (props) => <div>
<ProtectedHeader/>
 <Switch>
   <PrivateRoute exact path='/app/dashboard' component={Dashboard} />
   <Route component={NotFound} />
 </Switch>
<ProtectedFooter/>

Define high-level routes in app.js:

export default () => {
  return <div>
    <Switch>
      <Route path='/app' component={ProtectedLayout} />
      <Route path='/' component={PublicLayout} />
    </Switch>
  </div>
}

Define PrivateRoute:

export default ({component: Component, ...rest}) => (
  <Route {...rest} render={props => (
    window.globalState.isAuthenticated() ? (
      <Component {...props} />
    ) : (
      <Redirect to={{
        pathname: '/signin',
        state: {from: props.location}
      }} />
    )
  )} />
)

Yeah i know a bit late .

Visual studio 2019

import React from 'react';
import { Container } from 'reactstrap';
import NavMenu from '../components/NavMenu';

export default props => (
    <div>
        {window.location.pathname !== '/login' ? <NavMenu /> : null}        
        <Container>
            {props.children}
        </Container>
    </div>
);

i hope somebody helps out there.. !!! Happy coding

I made some solution while solving the problem.

First You can wrap the Switch in a website header and footer

<BrowserRouter>

    <WebsiteHeader />

    <Switch>
        <Route/>
        <Route/>
        <Route/>
    </Switch>

    <WebsiteFooter/>

<BrowserRouter>

then inside the header or footer wrap the components using withRouter from 'react-router-dom' so you can access the routes props

const WebsiteHeader = props => {
    if (props.location.pathname == "/register") return null;
    return (
        <Fragment>
            <DesktopHeader {...props} />
            <MobileHeader {...props} />
        </Fragment>
    );
};

export default withRouter(WebsiteHeader);

Use render

<ConnectedRouter history={history}>
  <Switch>
    <Route path="/dashboard" render={props => <Layout><Dashboard {...props} /></Layout>} />
    <Route path="/login" component={Login} />
  </Switch>
</ConnectedRouter>

For forcefully refresh Header inside routing. use forceRefresh={true}

const Routing = () => {
    return(
        <BrowserRouter forceRefresh={true}>
        <Header/>
        <Switch>
                <Route exact path="/" component={Home}/>
                <Route path="/list/:id" component={ListingApi}/>
                <Route path="/details/:id" component={HotelDetails}/>
                <Route path="/booking/:hotel_name" component={PlaceBooking}/>
                <Route path="/viewBooking" component={ViewBooking}/>
                <Route exact path="/login" component={LoginComponent}/>
                <Route  path="/signup" component={RegisterComponent}/>
        </Switch>
        <Footer/>
        </BrowserRouter>
    )
}

I would just create a few different layouts one with header and footer and one without. And then instead of wrapping everything into one layout. I'd just do this wrapping inside each page component. So your components would be like:

Dashboard component

<SimpleLayout>
  <Dashboard>
</SimpleLayout>

Home component

<MainLayout>
  <Home>
</MainLayout>

Try like this

<Route path="/" render={(props) => (props.location.pathname !== "/login") && 
    <Header />}>
</Route>

<Route path="/" render={(props) => (props.location.pathname !== "/login") && 
  <Menu />}> 
</Route>

<PrivateRoute path="/scope" component={Scope}  ></PrivateRoute>

<Route exact path="/login" component={Login} />

In this example I'm checking the URL, If the URL is "/Login" I'm removing Menu and header component

For forcefully refresh Header inside routing.

const Routing = () => {
    return(
        <BrowserRouter forceRefresh={true}>
        <Header/>
        <Switch>
                <Route exact path="/" component={Home}/>
                <Route path="/list/:id" component={ListingApi}/>
                <Route path="/details/:id" component={HotelDetails}/>
                <Route path="/booking/:hotel_name" component={PlaceBooking}/>
                <Route path="/viewBooking" component={ViewBooking}/>
                <Route exact path="/login" component={LoginComponent}/>
                <Route  path="/signup" component={RegisterComponent}/>
        </Switch>
        <Footer/>
        </BrowserRouter>
    )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM