Javascript React Router v4:导航更改时发送请求
我正在使用react router v4编写身份验证代码,并使用PrivateRoute和渲染道具,如文档: 我试图做的是:每当用户导航到某个路由时,我都要发送一个操作,向后端发出请求,以验证他是否已登录 像这样:Javascript React Router v4:导航更改时发送请求,javascript,reactjs,react-router,react-router-v4,Javascript,Reactjs,React Router,React Router V4,我正在使用react router v4编写身份验证代码,并使用PrivateRoute和渲染道具,如文档: 我试图做的是:每当用户导航到某个路由时,我都要发送一个操作,向后端发出请求,以验证他是否已登录 像这样: // App.js class App extends Component { checkAuth = () => { const { dispatch, } = this.props; // callback to dispatch } rend
// App.js
class App extends Component {
checkAuth = () => {
const { dispatch, } = this.props;
// callback to dispatch
}
render() {
const props = this.props;
return (
<Router>
<div className="App">
<Switch>
<Route exact path="/" component={Login} />
<PrivateRoute
exact
path="/dashboard"
component={Dashboard}
checkIsLoggedIn={this.checkAuth}
/>
{/* ... other private routes here */}
</Switch>
</div>
</Router>
);
}
//App.js
类应用程序扩展组件{
checkAuth=()=>{
const{dispatch,}=this.props;
//回拨
}
render(){
const props=this.props;
返回(
{/*…此处的其他专用路由*/}
);
}
在PrivateRoute.js中,我正在监听路由以检查它是否更改,但是当路由更改时,此函数被调用的次数太多,而这是一个调度操作以发出请求的问题
// PrivateRoute.js
const PrivateRoute = ({ component: Component, auth, checkIsLoggedIn, ...rest }) => (
<Route
{...rest}
render={props => {
props.history.listen((location, action) => {
if (checkIsLoggedIn) {
// Here I check if the route changed, but it render too many times to make a request
checkIsLoggedIn(); // here is the callback props
}
});
if (auth.login.isLoggedIn) {
return <Component {...props} />;
} else {
return <Redirect to={{ pathname: "/login", state: { from: props.location } }} />
}
}
}
/>
);
//privaterout.js
const privaterout=({component:component,auth,checkIsLoggedIn,…rest})=>(
{
道具。历史。聆听((位置、动作)=>{
如果(选中IsLoggedin){
//在这里,我检查路由是否已更改,但它呈现的次数太多,无法发出请求
checkIsLoggedIn();//这是回调道具
}
});
if(auth.login.isLoggedIn){
返回;
}否则{
返回
}
}
}
/>
);
我需要一个帮助来找出一个在路由改变时调用后端的好方法。创建一个是一个非常干净的方法。这样,您就不需要创建单独的PrivateRoute
组件,只需一行更改即可将任何组件从public转换为protected,反之亦然
像这样的方法应该会奏效:
import React from 'react';
import { Redirect } from "react-router-dom";
export function withAuth(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
isUserLoggedIn: false,
isLoading: true
};
}
componentDidMount() {
// Check for authentication when the component is mounted
this.checkAuthentication();
}
checkAuthentication() {
// Put some logic here to check authentication
// You can make a server call if you wish,
// but it will be faster if you read the logged-in state
// from cookies or something.
// Making a server call before every protected component,
// will be very expensive, and will be a poor user experience.
this.setState({
isUserLoggedIn: true, // Set to true or false depending upon the result of your auth check logic
isLoading: false
});
}
render() {
// Optionally, you can add logic here to show a common loading animation,
// or anything really, while the component checks for auth status.
// You can also return null, if you don't want any special handling here.
if (this.state.isLoading) return (<LoadingAnimation />);
// This part will load your component if user is logged in,
// else it will redirect to the login route
if (this.state.isUserLoggedIn) {
return <WrappedComponent authData={this.state} {...this.props} />;
} else {
return <Redirect to={{ pathname: "/login", state: { from: props.location } }} />;
}
}
}
}
在您的应用程序中
,您可以使用一个简单的路由
组件:
<Route exact path='/dashboard' component={Dashboard} />
您的应用程序
不需要关心哪些路由受保护,哪些路由不受保护。事实上,只有实际的组件需要知道它们受到了保护
希望这有帮助。干杯!:) 您可以在仪表板的方法
componentDidMount
中向后端发出请求component@ArnoldGandarillas但是我想在用户导航的每个私有路由中发出请求,privaterout
是一个自定义的React组件。这与反应路由器无关。将其更改为有状态类,并在其componentDidMount
方法中添加身份验证调用。@FisNaN我应该使用render props或HoC将其更改为类吗?HoC检查has perm是否是一个好方法使用HoC是一个很酷的主意,但我试图避免使用HoC,因为存在一个巨大的问题:如果我使用另一个HoC,它在“withAuth”中有一个同名的道具,那么它将发生冲突!由于道具冲突,我仍然不知道使用HoC是否是一个好主意。我认为与从应用程序
组件中抽象出auth逻辑所带来的好处相比,这是一个相对较小的问题。您可以将authData
道具重命名为模糊的名称,或者有意识地确保受保护组件中没有道具冲突。否则,如果您觉得您的仪表板
或其他组件不需要使用authData
,您甚至可以选择根本不传递它。
<Route exact path='/dashboard' component={Dashboard} />