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