首页 > 解决方案 > 如何正确等待这个 axios.get 请求?

问题描述

抱歉,如果这是我忽略的非常简单的事情,但是我正在尝试制作一个组件,该组件基本上将某些 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)”与未决的承诺一起执行,但最终结果是,我试图将一些逻辑编码到我的后端给出的响应中(真或假),然后应该将其发送到 PrivateRoute 组件以确定是否应将用户发送回登录等。

我知道这一定是因为 axios.get 的异步性质导致了我的问题,但我尝试了几种不同的方法:

使 isLogin 函数异步,然后等待 axios 请求

在 PrivateRoute 返回中创建另一个异步函数,带有等待。

似乎我在这里尝试的任何东西都没有正确地等待 axios.get 的结果,因此会给出不需要的结果。如果有任何建议,甚至是正确的前进方向,我将不胜感激。

谢谢你。

标签: javascriptreactjsasynchronousaxiosreact-router-dom

解决方案


正如@Emile Bergeron 在评论(引用)中所说,我将向私有路由组件添加一个状态,如果用户通过身份验证,它将存储。这将在组件(私有路由)第一次挂载时进行检查。

作为代码,以您的代码为基础,它看起来像这样:

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;

编辑:当然,您还需要加载过程的状态,因此在获取用户之前重定向不会击中您。


推荐阅读