React Router - 如何在 404 页面上隐藏组件

React Router - How to hide components on 404 page

我正在使用 React 构建应用程序并使用 React Router 来管理路由。我目前正在处理 404 错误。我的问题是我的应用程序在显示我创建的 404 页面时显示我的导航栏和子页脚和页脚。隐藏这 3 个组件的最佳方法是什么?

我的 app.js 目前看起来像这样..

class App extends Component {
  
  render() {
    return (
      <div className="body">
      <div className="App">
        <BrowserRouter>
          <NavBar />
          <Switch>
            <Route exact path="/" component={Home} exact={true} />
            <Route exact path="/projects" component={Projects} />
            <Route component={PageNotFound}/>
            <Redirect to="/404" /> 
          </Switch>
          <SubFooter/>
          <Footer />
        </BrowserRouter>
      </div>
      </div>
    );
  }
}

您需要创建一个主路由,其中​​包含主应用程序的路由(包含导航 + 内容路由 + 页脚)和 404 页面的路由:

const Main = () => (
  <BrowserRouter>
    <Switch>
      <Route path="/404" exact render={() => <div>404</div>} />
      <Route path="/" component={App} />
    </Switch>
  </BrowserRouter>
);

对于应用程序 js:

import React from "react";
import { Redirect, Route, Switch } from "react-router-dom";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <div>navbar</div>
      <div>footer</div>
      <Switch>
        <Route path="/" exact render={() => <div>home</div>} />
        <Route exact path="/projects" render={() => <div>projects</div>} />
        <Redirect to="/404" />
      </Switch>
    </div>
  );

这里有完整的例子:example

注意:您需要将 404 路由放在主应用程序路由之前才能首先匹配。

你可以为错误做一个类似这样的布局:

layout/Error404.js

  import React, { Suspense } from 'react';

  export const ErrorLayout = (props) => {
  const { children } = props;  

  return (
    <div>
      <div>
        <Suspense fallback={"loading..."}>
          {children}
        </Suspense>
      </div>
    </div>
  );
}
 

layout/publicLayout.js

  import React, { Suspense } from 'react';

  export const PublicLayout = (props) => {
  const { children } = props;  

  return (
    <div>
      <NavBar />
      <div>
        <Suspense fallback={"loading..."}>
          {children}
        </Suspense>
      </div>
      <SubFooter/>
      <Footer />
    </div>
  );
}
 

并创建自定义路由来呈现您需要的内容,例如:

routes/myErrorRoute.js

import React from "react";

export const ErrorRouteLayout = (props) => {
  const { layout: Layout, component: Component, ...rest } = props;

  return (
    <Route
      {...rest}
      render={(matchProps) =>
         Layout? (
          <Layout>
            <Component {...matchProps} />   
          </Layout>
        ) : (
          <Component {...matchProps} />
        )
      }
    />
  );
};
    

routes/publicRoute.js

import React from "react";

export const PublicRouteLayout = (props) => {
  const { layout: Layout, component: Component, ...rest } = props;

  return (
    <Route
      {...rest}
      render={(matchProps) =>
         Layout? (
          <Layout>
            <Component {...matchProps} />   
          </Layout>
        ) : (
          <Component {...matchProps} />
        )
      }
    />
  );
};

最后,您的 app.js 应该看起来像这样

import { ErrorLayout  }  from './layout/Error404'
import { PublicLayout  }  from './layout/publicLayout'
import { ErrorRouteLayout   } from './routes/myErrorRoute'
import { PublicRouteLayout    } from './routes/publicRoute'


class App extends Component {
  
  render() {
    return (
      <div className="body">
      <div className="App">
        <BrowserRouter>
          <PublicRouteLayout 
            component={YourComponent}
            exact
            path="/home"
            layout={PublicLayout}
           />
          <ErrorRouteLayout 
            component={YourComponent}
            exact
            path="/error404"
            layout={ErrorLayout}
           />
            
            <Redirect to="/404" /> 
          </Switch>
        </BrowserRouter>
      </div>
      </div>
    );
  }
}