ReactJs: проблема с настройкой частного маршрута - PullRequest
0 голосов
/ 17 февраля 2020

В предыдущем проекте я успешно настроил частный маршрут, создав компонент PrivateRoute и используя его в приложении. 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);

Приложение. js

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

Это работает отлично .
В новый проект, маршруты настроены немного по-другому в приложении. js:

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

Обратите внимание, что вместо использования:

component={DefaultLayout}

This используется:

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

И так как компонент Private route принимает компонент в качестве реквизита, имел смысл, что это не будет работать:

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

Итак, я попытался вместо этого передайте компонент DefaultLayout:

Это также не работает, но я получаю без ошибок . После входа в систему я получаю пустой экран (я должен быть перенаправлен на домашнюю страницу).

ЗАМЕЧАНИЕ 1: Когда я передаю другой компонент вместо DefaultLayout в частный маршрут, вся логика частного маршрута c работает отлично. Так что, я полагаю, это как-то связано с компонентом панели мониторинга . Итак, вот определение ** 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);

REMARK 2: Когда установлен маршрут к компоненту DefaultLayout при нормальном маршруте код работает нормально:

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

Итак, как заключение, поскольку (1) riPrivateRoute работал с обычными компонентами и DefaultLayout route действительно работает , когда он настроен с использованием обычного 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, я получаю пустой экран.
Поэтому я попытался добавить его вручную в App. js:

 <Switch>
      <PrivateRoute
        exact
        name="Home"
        path="/home"
        component={DefaultLayout}
      />
      <PrivateRoute
        exact
        name="Dashboard"
        path="/home/dashboard"
        component={DefaultLayout}
      />
    </Switch>  

, который заставил его работать. Но я не могу сделать это для каждого sub-Route . Компонент DashboardLayout должен маршрутизироваться изнутри себя, не возвращаясь к маршрутам App. js, если это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...