在上一个项目中,我通过创建 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 路由。