【问题标题】:How to skip header and footer for certain routes in ReactJS?如何在 ReactJS 中跳过某些路由的页眉和页脚?
【发布时间】:2019-01-18 15:36:02
【问题描述】:

我有以下代码,它为所有页面呈现带有页眉和页脚的应用程序。

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>
        )
    }
}

对于某些页面(如主页和登录路由)跳过页眉和页脚的呈现的最佳方法是什么?

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    用于在路由中强制刷新 Header。

    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>
        )
    }
    

    【讨论】:

      【解决方案2】:

      用于在路由中强制刷新 Header。 使用 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>
          )
      }
      

      【讨论】:

        【解决方案3】:

        这样试试

        <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} />
        

        在此示例中,我正在检查 URL,如果 URL 是“/Login”,我将删除 Menuheader 组件

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关其解决问题的方式和/或原因的附加上下文将提高​​答案的长期价值。Read this
        【解决方案4】:

        我在解决问题的同时做了一些解决方案。

        首先您可以将Switch 包装在网站页眉和页脚中

        <BrowserRouter>
        
            <WebsiteHeader />
        
            <Switch>
                <Route/>
                <Route/>
                <Route/>
            </Switch>
        
            <WebsiteFooter/>
        
        <BrowserRouter>
        

        然后在页眉或页脚内使用来自'react-router-dom'withRouter 包装组件,以便您可以访问路由道具

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

        【讨论】:

        • 我认为WebsiteHeader 无法接收props.location,因为它不在开关中!
        【解决方案5】:

        是的,我知道有点晚了。

        视觉工作室 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>
        );
        

        我希望有人能帮忙.. !!!快乐编码

        【讨论】:

          【解决方案6】:

          使用render

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

          【讨论】:

            【解决方案7】:

            我建议创建两个带有自己的页眉和页脚以及私有路由的布局:

            公共布局

            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/>
            

            受保护的布局

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

            在 app.js 中定义高级路由:

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

            定义 PrivateRoute:

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

            【讨论】:

            • 这似乎是一个更清洁的解决方案。我试试看。
            • 你能帮我提供同样的类组件解决方案吗?
            • 嗨,有人可以解释为什么在 app.js 的高级路由中,路由的顺序很重要。我尝试了同样的方法,但最终颠倒了顺序,应用程序不起作用。
            【解决方案8】:

            我会创建一些不同的布局,一种带有页眉和页脚,另一种没有。然后不是将所有内容包装到一个布局中。我只是在每个页面组件内进行此包装。所以你的组件会是这样的:

            仪表板组件

            <SimpleLayout>
              <Dashboard>
            </SimpleLayout>
            

            首页组件

            <MainLayout>
              <Home>
            </MainLayout>
            

            【讨论】:

              猜你喜欢
              • 2017-03-20
              • 2016-09-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-01-27
              • 1970-01-01
              • 1970-01-01
              • 2019-03-12
              相关资源
              最近更新 更多