很抱歉,如果我忽略了这件事非常简单,但是我试图制造一个组件,该组件基本上只将某些React-Router路由限制为仅具有有效令牌的用户。
import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';
function isLogin(){
const result = Axios.get('http://localhost:8081/authentication', {withCredentials: true})
.then(res => {
console.log(res);
})
console.log(result);
}
const PrivateRoute = ({component: Component, ...rest}) => {
return (
<Route {...rest} render={props => (
isLogin() ?
<Component {...props} />
: <Redirect to="/login" />
)} />
);
};
export default PrivateRoute;
似乎(仅预期)仅使用未完成的promise执行“ console.log(result)”,但最终结果是,我尝试将一些逻辑编码到后端给出的响应中(true或false),然后应将其向下发送到PrivateRoute组件,以确定是否应将用户发送回登录名等。
我知道这一定是因为axios.get的异步特性导致了我的问题,但是我尝试了几种不同的方法:
使isLogin函数异步,然后等待axios请求
在PrivateRoute返回中的另一个异步创建函数,等待。
似乎我在这里尝试执行的操作都没有正确等待axios.get的结果,从而导致产生不必要的结果。 希望您能提供任何建议,甚至是正确的方向。
谢谢。
答案 0 :(得分:0)
正如@Emile Bergeron在评论(引用)中所说,我将向私有Route组件添加一个状态,如果用户通过了身份验证,该状态将存储。首次安装组件(专用路由)时,将对此进行检查。
作为代码,以您的代码为基础看起来像这样:
import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';
const PrivateRoute = ({component: Component, ...rest}) => {
// State
const [authenticated, setAuthentication] = useState(null);
const [loadingComplete, setLoadingComplete] = useState(false);
// Login function
useEffect(
() => {
// ComponentDidMount
// Declare Function (you can also declare it outside the useEffect,
// if you want to run it also if another prop changes for instance.
// But it will be overwritten on every rerender;
// To prevent this you could use useCallback hook)
const isLogin = async () => {
try {
const result = await Axios.get('http://localhost:8081/authentication', {withCredentials: true});
// Store the result, e.g. ID, token, ...
setAuthentication(result);
} catch (e) {
// Something failed
console.log(e);
}
setLoadingComplete(true);
}
// run login function
isLogin();
},
[]
);
if(loadingComplete){
return (
<Route {...rest} render={props => (
!!authenticated ?
<Component {...props} />
: <Redirect to="/login" />
)} />
);
}else{
return ( <div> Loading... </div>);
}
};
export default PrivateRoute;
编辑:当然,您还需要一个加载过程状态,因此重定向不会在您获取用户之前命中您。
答案 1 :(得分:0)
我已经制作了gist来处理这种情况。
您需要2个状态。
您将具有一个对用户进行身份验证的功能,但在身份验证时还需要一个加载状态。
所以您会得到
return (
<Route
{...rest}
render={props => (
!isLoading
?
(
isAuthenticated
?
<Component {...props} />
:
<Redirect to="/login" />
)
:
<Loading />
)}
/>
)
您将拥有一个可以设置这些状态的函数
useEffect(() => {
setIsLoading(true)
isLogin()
.then(() => {
setIsAuthenticated(true)
})
.catch(() => {
setIsAuthenticated(false)
})
.then(() => {
setIsLoading(false)
})
}, [])