React Private Route 高阶组件?
Posted
技术标签:
【中文标题】React Private Route 高阶组件?【英文标题】:React Private Route higher order component? 【发布时间】:2019-04-01 01:40:15 【问题描述】:我正在尝试制作一个 PrivateRoute 组件以进行反应。这是我的高阶组件。你能告诉我这是什么问题吗?
import React from "react";
import Route, Redirect from "react-router-dom";
import connect from "react-redux";
export default ( component: Component, ...rest ) =>
class PrivateRoute extends React.Component
render()
console.log("This is private route called");
if (this.props.profile)
return (
<Route
...rest
render=props =>
this.props.profile.loggedIn === true ? (
<Component ...props />
) : (
<Redirect to="/login" />
)
/>
);
const mapStateToProps = state => (
profile: state.profile
);
return connect(mapStateToProps)(PrivateRoute);
;
【问题讨论】:
您遇到的错误是什么?猜测是你可能需要扩展 React.Component 而不是你传递的 Component.. @AlexG 我已经实现了 React.Component。好吧,我实际上并没有收到任何错误。当我使用它访问路线时,什么都没有呈现。 @AlexG 我正在从这篇文章中实现它tylermcginnis.com/react-router-protected-routes-authentication 在您正在实施的示例中,privateAuth 是一个 Route 组件,而不是另一个呈现 Route 的组件。尝试简单地返回路线。 【参考方案1】:这是通过受保护路由组件完成受保护路由的方法。
工作示例:https://codesandbox.io/s/yqo75n896x
容器/RequireAuth.js
import React from "react";
import Route, Redirect from "react-router-dom";
import connect from "react-redux";
import ShowPlayerRoster from "../components/ShowPlayerRoster";
import ShowPlayerStats from "../components/ShowPlayerStats";
import Schedule from "../components/Schedule";
const RequireAuth = ( match: path , isAuthenticated ) =>
!isAuthenticated ? (
<Redirect to="/signin" />
) : (
<div>
<Route exact path=`$path/roster` component=ShowPlayerRoster />
<Route path=`$path/roster/:id` component=ShowPlayerStats />
<Route path=`$path/schedule` component=Schedule />
</div>
);
export default connect(state => (
isAuthenticated: state.auth.isAuthenticated
))(RequireAuth);
routes/index.js
import React from "react";
import BrowserRouter, Route, Switch from "react-router-dom";
import createStore from "redux";
import Provider from "react-redux";
import Home from "../components/Home";
import Header from "../containers/Header";
import Info from "../components/Info";
import Sponsors from "../components/Sponsors";
import Signin from "../containers/Signin";
import RequireAuth from "../containers/RequireAuth";
import rootReducer from "../reducers";
const store = createStore(rootReducer);
export default () => (
<Provider store=store>
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path="/" component=Home />
<Route path="/info" component=Info />
<Route path="/sponsors" component=Sponsors />
<Route path="/protected" component=RequireAuth />
<Route path="/signin" component=Signin />
</Switch>
</div>
</BrowserRouter>
</Provider>
);
或者,如果您想要包含所有路由的东西(而不是必须指定受保护的路由组件)。然后您可以执行以下操作。
工作示例:https://codesandbox.io/s/5m2690nn6n
components/RequireAuth.js
import React, Component, Fragment from "react";
import withRouter from "react-router-dom";
import Login from "./Login";
import Header from "./Header";
class RequireAuth extends Component
state = isAuthenticated: false ;
componentDidMount = () =>
if (!this.state.isAuthenticated)
this.props.history.push("/");
;
componentDidUpdate = (prevProps, prevState) =>
if (
this.props.location.pathname !== prevProps.location.pathname &&
!this.state.isAuthenticated
)
this.props.history.push("/");
;
isAuthed = () => this.setState( isAuthenticated: true );
unAuth = () => this.setState( isAuthenticated: false );
render = () =>
!this.state.isAuthenticated ? (
<Login isAuthed=this.isAuthed />
) : (
<Fragment>
<Header unAuth=this.unAuth />
this.props.children
</Fragment>
);
export default withRouter(RequireAuth);
routes/index.js
import React from "react";
import BrowserRouter, Switch, Route from "react-router-dom";
import Home from "../components/Home";
import Players from "../components/Players";
import Schedule from "../components/Schedule";
import RequireAuth from "../components/RequireAuth";
export default () => (
<BrowserRouter>
<RequireAuth>
<Switch>
<Route exact path="/" component=Home />
<Route exact path="/players" component=Players />
<Route path="/schedule" component=Schedule />
</Switch>
</RequireAuth>
</BrowserRouter>
);
或者,如果您想要更模块化的东西,您可以选择任何路线,那么您可以创建一个包装器HOC
。请参阅此example(虽然它是为 v3 而不是为身份验证而编写的,但它仍然是相同的概念)。
【讨论】:
我知道这里不允许这种cmets..但是我想说'非常感谢'...???【参考方案2】:看起来你的渲染函数的唯一返回是在 if 块内,所以它返回 null。您需要修复逻辑以仅返回 Route 并将 profile 作为 proptypes 检查中的必需道具,而不是使用 if 块。
PrivateRoute.propTypes =
profile: PropTypes.object.isRequired
;
【讨论】:
以上是关于React Private Route 高阶组件?的主要内容,如果未能解决你的问题,请参考以下文章