如何正确等待这个 axios.get 请求?
Posted
技术标签:
【中文标题】如何正确等待这个 axios.get 请求?【英文标题】:How to properly await this axios.get request? 【发布时间】:2020-04-13 04:52:32 【问题描述】:对不起,如果这是我忽略的极其简单的事情,但我正在尝试制作一个组件,该组件基本上将某些 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;
似乎(如预期的那样)只有“console.log(result)”会使用未决的承诺执行,但最终结果是,我试图将一些逻辑编码到后端给出的响应中(true 或false),然后应将其发送到 PrivateRoute 组件以确定是否应将用户发送回登录等。
我知道这一定是因为 axios.get 的异步特性导致了我的问题,但我尝试了几种不同的方法:
使 isLogin 函数异步,然后等待 axios 请求
在 PrivateRoute 返回中创建另一个异步函数,带有等待。
似乎我在这里尝试的任何东西都没有正确等待 axios.get 的结果,因此会给出不需要的结果.. 非常感谢任何建议,甚至是正确的前进方向。
谢谢。
【问题讨论】:
让我们专注于期望。发送请求但尚未返回响应后,您希望看到什么? 您不能在渲染流程中直接使用异步代码。身份验证完成后更新状态。 这能回答你的问题吗? How to perform authentication with React hooks and react-router Additional information on handling auth in React 您应该在登录后将令牌存储在本地存储或cookie中。然后获取该令牌以查看用户是否已登录。不应该以这种方式使用异步逻辑 【参考方案1】:正如@Emile Bergeron 在 cmets (引用)中所说,我将向私有 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;
编辑:当然,您还需要加载过程的状态,因此在获取用户之前重定向不会影响您。
【讨论】:
我肯定是从错误的角度看待这个问题,在合并了你的大部分代码之后(尤其是使用 State 来存储这些变量的要点),它完美地工作。非常感谢你,以及所有在这里回答的人。【参考方案2】:我已经创建了一个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)
)
, [])
【讨论】:
以上是关于如何正确等待这个 axios.get 请求?的主要内容,如果未能解决你的问题,请参考以下文章