ReactJs:设置专用路由的问题

时间:2020-02-17 15:48:23

标签: reactjs react-router react-router-v4 react-router-dom react-router-component

在上一个项目中,我通过创建 PrivateRoute 组件并将其在App.js中使用,成功设置了私有路由,如下所示:

PrivateRoute.js

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      auth.isAuthenticated === true ? (
        <Component {...props} />
      ) : (
        <Redirect to="/" />
      )
    }
  />
);

PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(mapStateToProps)(PrivateRoute);

App.js

           <Switch>
                <PrivateRoute
                  exact
                  path="/dashboard"
                  component={Dashboard}
                ></PrivateRoute>
              </Switch>

完全有效。
在新项目中, App.js 中的路由设置有所不同:

<Route
        path="/home"
        name="Home"
        render={props => <DefaultLayout {...props} />
      /> 

请注意,不要使用:

component={DefaultLayout}

正在使用:

render={props => <DefaultLayout {...props} />  

并且由于专用路由组件将输入组件作为道具,因此这是行不通的:

   <PrivateRoute
                exact
                name="Home"
                path="/home"
                render={props => <DefaultLayout {...props} />}
              />  

因此,我尝试改为传递DefaultLayout组件:

这也行不通,但我没有错误。登录后,我得到一个黑屏(应该重定向到主页。)。

注释1:当我将另一个组件而不是 DefaultLayout 组件传递给专用路由时,整个专用路由逻辑有效 。因此,我认为这与仪表板组件本身有关。所以这是** DefaultLayout.js的定义:**

import React, { Component, Suspense } from "react";
import { Redirect, Route, Switch } from "react-router-dom";
import * as router from "react-router-dom";
import { Container } from "reactstrap";

import {
  AppAside,
  AppFooter,
  AppHeader,
  AppSidebar,
  AppSidebarFooter,
  AppSidebarForm,
  AppSidebarHeader,
  AppSidebarMinimizer,
  AppBreadcrumb2 as AppBreadcrumb,
  AppSidebarNav2 as AppSidebarNav
} from "@coreui/react";
// sidebar nav config
import navigation from "../../_nav";
// routes config
import routes from "../../routes";
import { logoutUser } from "../../actions/authActions";
import PropTypes from "prop-types";
import { connect } from "react-redux";
const DefaultAside = React.lazy(() => import("./DefaultAside"));
const DefaultFooter = React.lazy(() => import("./DefaultFooter"));
const DefaultHeader = React.lazy(() => import("./DefaultHeader"));

class DefaultLayout extends Component {
  loading = () => (
    <div className="animated fadeIn pt-1 text-center">Loading...</div>
  );

  signOut(e) {
    e.preventDefault();
    this.props.logoutUser();
    this.props.history.push("/");
  }

  render() {
    return (
      <div className="app">
        <AppHeader fixed>
          <Suspense fallback={this.loading()}>
            <DefaultHeader onLogout={e => this.signOut(e)} />
          </Suspense>
        </AppHeader>
        <div className="app-body">
          <AppSidebar fixed display="lg">
            <AppSidebarHeader />
            <AppSidebarForm />
            <Suspense>
              <AppSidebarNav
                navConfig={navigation}
                {...this.props}
                router={router}
              />
            </Suspense>
            <AppSidebarFooter />
            <AppSidebarMinimizer />
          </AppSidebar>
          <main className="main">
            <AppBreadcrumb appRoutes={routes} router={router} />
            <Container fluid>
              <Suspense fallback={this.loading()}>
                <Switch>
                  {routes.map((route, idx) => {
                    return route.component ? (
                      <Route
                        key={idx}
                        path={route.path}
                        exact={route.exact}
                        name={route.name}
                        render={props => <route.component {...props} />}
                      />
                    ) : null;
                  })}
                  <Redirect from="/home" to="/home/dashboard" />
                </Switch>
              </Suspense>
            </Container>
          </main>
          <AppAside fixed>
            <Suspense fallback={this.loading()}>
              <DefaultAside />
            </Suspense>
          </AppAside>
        </div>
        <AppFooter>
          <Suspense fallback={this.loading()}>
            <DefaultFooter />
          </Suspense>
        </AppFooter>
      </div>
    );
  }
}

DefaultLayout.propTypes = {
  logoutUser: PropTypes.func.isRequired
};

export default connect(null, { logoutUser })(DefaultLayout);

备注2:当使用常规路由设置到 DefaultLayout 组件的路由时,代码可以正常工作:

            <Route
            path="/home"
            name="Home"
            render={props => <DefaultLayout {...props} />}
          />  

因此可以得出结论,因为(1)-“ PrivateRoute 可以正常使用,并且 DefaultLayout 路由可以正常工作< / strong>,使用普通的 Route 组件进行设置。
==我想这个问题是 PrivateRoute 组件被设置为可以接收普通组件吗?
但是,我不知道如何准确修复它或使其适应DashboardLayout组件。

编辑1: DefaultLayout.js中的路由:

<Switch>
                  {routes.map((route, idx) => {
                    return route.component ? (
                      <Route
                        key={idx}
                        path={route.path}
                        exact={route.exact}
                        name={route.name}
                        render={props => <route.component {...props} />}
                      />
                    ) : null;
                  })}
                  <Redirect from="/home" to="/home/dashboard" />
                </Switch> 

因此,在用户登录后,它会重定向到 / home / dashboard ,但是由于未在 App.js 中定义此路由,所以我得到了一个空白屏幕。 br /> 因此,我尝试在 App.js:

中手动添加它
 <Switch>
      <PrivateRoute
        exact
        name="Home"
        path="/home"
        component={DefaultLayout}
      />
      <PrivateRoute
        exact
        name="Dashboard"
        path="/home/dashboard"
        component={DefaultLayout}
      />
    </Switch>  

这使它起作用。但是,我不能为每个子路由执行此操作。 DashboardLayout 组件应该从自身内部进行路由,而不需要返回到 App.js 路由。

0 个答案:

没有答案