首页 > 解决方案 > React Router v5.0 嵌套路由

问题描述

我正在构建一个反应应用程序,但我无法使路由工作。

  1. 我需要一些 Auth 路由(、、、等)的通用布局(页眉/loginsign-up页脚forgot-password

  2. 而且我需要为应用程序的其余受保护部分(,,等...)使用另一种Home通用Dashboard布局

  3. 我需要另一个没有任何布局的 404 页面。

我从这些链接中尝试了几种技术:

但可以达到工作版本。

这是我目前拥有的:

(注意:现在我忽略了阻止非登录用户进入 AppLayout 的私有路由的需要,我会在之后处理)

const App: React.FC = () => {
    const history = createBrowserHistory();

    return (
        <div className="App">
            <Router history={history}>
                <Switch>
                    <AppLayout>
                        <Route path="/home" component={HomePage}/>
                        <Route path="/dashboard" component={DashboardPage}/>
                        ...
                    </AppLayout>
                    <AuthLayout>
                        <Route path="/login" component={LoginPage}/>
                        <Route path="/sign-up" component={SignUpPage}/>
                        ...
                    </AuthLayout>
                    <Route path="*" component={NotFoundPage} />
                </Switch>
            </Router>
        </div>
    );
};

export default App;

两者AuthLayoutAppLayout都简单且相似(只是每个都有不同的页眉/页脚):

class AppLayout extends Component {
    render() {
        return (
            <div className="AppLayout">
                <header>...</header>
                {this.props.children}
                <footer>...</footer>
            </div>
        );
    }
}

export default AppLayout;

问题是只呈现来自 AppLayout 的路由。其他路由只显示 AppLayoutheaderfooter没有任何内容。

这些是我正在使用的反应版本:

    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-router-dom": "^5.0.0",

任何帮助,将不胜感激。

提前致谢。

标签: reactjsreact-router

解决方案


您的每个布局都应该有一个路径组件以区别于其他布局。

例如

Auth 布局可以驻留在/auth例如 login/auth/login和 signup 下/auth/signup

应用程序布局可以在下面,/app例如,仪表板是/app/dashboard,主页是/app/home

工作演示

编辑饥饿-dubinsky-q1l62

应用程序.js

import { Switch, BrowserRouter, Route, Redirect } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      <Layouts />
    </BrowserRouter>
  );
}

布局.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>
  );
}

授权布局

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} />
      <Redirect from="/auth" to="/auth/login" exact />
    </div>
  );
}

应用布局

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} />
      <Redirect from="/app" to="/app/home" exact />
    </div>
  );
}

此外,如果您想保护某些路由在未经身份验证的情况下不被渲染,那么您可以创建一个PrivateRoute组件,如果未经身份验证,该组件将重定向到身份验证布局。

PrivateRoute.js

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props => sessionStorage.token // your auth mechanism goes here
      ? <Component {...props} />
      : <Redirect to={{ pathname: '/auth' }} />}
  />
);

您可以使用此PrivateRoute组件代替react-router'Route组件。

例如:

<PrivateRoute path="/app" component={AppLayout} />


推荐阅读