在React Router dom v5中嵌套的路由和未找到的路由

时间:2020-06-20 14:53:36

标签: reactjs react-router react-router-dom react-router-v5

在尝试在react router dom v5中创建嵌套路由时,我发现this answer解释了如何做得很好

(请看一下这里的代码,因为它与上面提到的答案有些不同)

Layouts.js

const NotFound = () => <h1>Not Found</h1>;

function Layouts() {
  return (
    <Switch>
      <Route path="/auth" component={AuthLayout} />
      <Route path="/app" component={AppLayout} />
      <Route path="/" component={NotFound} />
    </Switch>
  );
}

AuthLayout

const Signup = () => <p>Login</p>;
const Login = () => <p>Sign up</p>;

function AuthLayout() {
  return (
    <div>
      <h1>Auth Layout</h1>
      <Route path="/auth/signup" exact component={Signup} />
      <Route path="/auth/login" exact component={Login} />
      {/* Commenting this because I want to go to NotFound component */}
      {/* <Redirect from="/auth" to="/auth/login" exact /> */}
    </div>
  );
}

AppLayout

const Home = () => <p>Home</p>;
const Dashboard = () => <p>Dashboard</p>;

function AppLayout() {
  return (
    <div>
      <h1>App Layout</h1>
      <Route path="/app/home" exact component={Home} />
      <Route path="/app/dashboard" exact component={Dashboard} />
      {/* Commenting this because I want to go to NotFound component */}
      {/* Redirect from="/app" to="/app/home" exact /> */}
    </div>
  );
}

但这有一个问题,如果您使用/app/somethingnotfound进入一条路线,而不会到达<Route path="/" component={NotFound} />,则它将“停留在” AppLayout中并且不呈现任何路线。

在这种情况下,如何使/app/somethingnotfound转到<Route path="/" component={NotFound} />

编辑:

请更加清楚:我不想只在<Route component={NotFound} />AuthLayout内添加AppLayout,因为它会渲染其他内容。我真正需要的是显示最高级别的NotFound

3 个答案:

答案 0 :(得分:1)

找不到组件通常是这样的:

<Router>
  <Switch>
    <Route exact path="/auth" component={AuthLayout} />
    <Route exact path="/app" component={AppLayout} />
    <Route component={NotFound} />
  </Switch>
</Router>

但是您无法将/auth/app标记为exact,因为它们包含嵌套路由。因此,您应该这样做:

<Router>
  <Switch>
    <Route path="/auth" component={AuthLayout} />
    <Route path="/app" component={AppLayout} />
    <Route exact path="/404" component={NotFound} />
    <Redirect to='/404' />
  </Switch>
</Router>

和具有嵌套路由的组件(例如AppLayout

<>
<h1>App Layout</h1>
<Switch>
  <Route path="/app/home" exact component={Home} />
  <Route path="/app/dashboard" exact component={Dashboard} />
  <Redirect to="/404" />
</Switch>
</>

答案 1 :(得分:0)

在查看我发现的this solution的github问题时,您会创建一个“全局未找到的页面”,如果找不到路由,则通过该页面通过状态,然后仅渲染该路由而不是其他路由。

const NotFound = () => <div className="not_found"><h1>Not Found</h1></div>;

const RouteNotFound = () => <Redirect to={{ state: { notFoundError: true } }} />;

const CaptureRouteNotFound = withRouter(({children, location}) => {
  return location && location.state && location.state.notFoundError ? <NotFound /> : children;
});

const Settings = () => {
  return (
    <Switch>
      <Route path="/settings/account" render={() => <h1>Account Settings</h1>} />
      <Route path="/settings/profile" render={() => <h1>Profile Settings</h1>} />

      <RouteNotFound />
    </Switch>
  );
};

const AppShell = ({children}) => {
  return (
    <div className="application">
      <header>Application</header>
      {children}
    </div>
  );
};

const Application = () => {
  return (
    <Router>
      <CaptureRouteNotFound>
        <AppShell>
          <Switch>
            <Route path="/settings" render={() => <Settings />} />
            <Route path="/profile" render={() => <h1>User Profile</h1>} />

            <RouteNotFound />
          </Switch>
        </AppShell>
      </CaptureRouteNotFound>
    </Router>
  );
};

答案 2 :(得分:0)

<Route path="/" component={NotFound} />与所有未实现的嵌套都不匹配,因为Switch组件中的Layouts将仅呈现与Route。在您的情况下,当您通过路径pathname时,它将路由与AppLayout组件匹配,这就是为什么它仅呈现/app/somethingdoesntexist组件的原因。

解决方案

例如,最好使用嵌套的AppLayout组件为每个布局实现NotFound路由

Switch

在上述情况下,我们使用function AppLayout() { const { path, url } = useRouteMatch(); return ( <Switch> <Route path={`${path}/home`} exact component={Home} /> <Route path={`${path}/dashboard`} exact component={Dashboard} /> <Route path="*" component={NotFound} /> </Switch> ); } 钩子获得了匹配的路径,并嵌套了另一个useRouteMatch组件,该组件将呈现与Switch匹配的任何嵌套路由,并提供后备{ {1}}将路径指定为path,将在找不到匹配项时呈现Route组件。

这是解决方案的完整示例 codesandbox

您还可以看到文档中提供的嵌套example