首页 > 解决方案 > 在 API 请求之前读取变量值(更改其值)

问题描述

我正在尝试对我的应用程序中的用户进行身份验证。运行此代码时,console.log("this", isAuthenticated);在 const 之前执行(或至少显示在控制台中)checkLoginStatus = () => {...};。供参考,见下文。

我也尝试使用useState,但也没有成功。

    import React, { useEffect, useState } from "react";
    import { Redirect, Route } from "react-router-dom";
    import axios from 'axios'
    
    function ProtectedRoute({ component: Component, ...restOfProps }) {
    
        // const [isAuthenticated, setIsAuthenticated] = useState(false);
        var isAuthenticated = null;
        useEffect(() => {
         checkLoginStatus()
        }, []);
        
        const checkLoginStatus = () => {
            axios
                .get(`${process.env.REACT_APP_API_URL}/session/extend`, { withCredentials: true })
                .then(response => {
                    // logged in
                    //setIsAuthenticated(true);
                    isAuthenticated = true;
                    console.log("logged in") // second in the console
                    console.log(response);
                    return true;
                })
                .catch((error) => {
                    // not logged in
                    //setIsAuthenticated(false);
                    isAuthenticated = false;
                    console.log(error)
                    return false;
                });
        };
        //checkLoginStatus();
        // setTimeout(function() {
        //     console.log("this", isAuthenticated);
        // }, 2000);
        console.log("this", isAuthenticated); // first in the console
    
        return (
            <Route
                {...restOfProps}
                render={(props) =>
                    isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />
                }
            />
        );
    }
    
    export default ProtectedRoute;

我该如何解决这个问题?

标签: javascriptreactjsaxios

解决方案


这里有两种情况:

  1. 状态变量 isAuthenticated
  2. 局部变量 isAuthenticated

对于案例2:原因很简单,API调用是异步的并且没有改变组件的状态,渲染只发生一次,而且在API调用执行之前也是如此,因此第二个console.log语句先执行然后再执行第一个 console.log 被执行。这里要注意的一件事是,对 isAuthenticated 的更改不会触发更新后的 isAuthenticated 变量的重新渲染。

对于案例 1:这是一个非常有趣的案例,其中有一个非常奇特的 useEffect 特征。在 useEffect 中针对每个状态更改进行任何异步调用后,将触发重新渲染。当您更改状态变量 isAuthenticated 时发生的情况是再次触发重新渲染,然后执行 setIsAuthenticated 语句之后的下一个 console.log 语句。这导致第二个 console.log 语句被执行,在它在初始渲染的早些时候执行之后,在 API 调用中存在的第一个 console.log 语句被执行之前。

关于这个的一个很好的 subreddit:https ://www.reddit.com/r/reactjs/comments/lhj7nb/batching_usestate_in_async_useeffect/


推荐阅读