为什么反应setState无法正常工作?

问题描述 投票:0回答:2
IM创建包装器以检查身份验证服务器响应是预期的,但是以某种方式iSauthenticatiencated状态不会更改为true。

import React, { useState, useEffect } from "react"; import { Navigate } from "react-router-dom"; import Cookies from "js-cookie"; import axios from "axios"; function PrivateRoute({ children }) { const [isAuthenticated, setIsAuthenticated] = useState(false); async function checkAuth() { try { axios.defaults.withCredentials = true; const sessionId = Cookies.get("sessionId"); const data = { sessionId: sessionId, }; if (sessionId) { const response = await axios.get("http://127.0.0.1:5000/session", { params: data, }); console.log(response.status); if (response.status === 200) { console.log("authenticated"); setIsAuthenticated(true); } else { console.log("unauthenticated"); setIsAuthenticated(false); } } } catch (err) { console.error(err); setIsAuthenticated(false); } } checkAuth(); console.log(isAuthenticated); return isAuthenticated ? children : <Navigate to="/login" />; } export default PrivateRoute;

IVE试图在我的if语句中登录它,并且它有效,并且在调用CheckAuth函数后记录iSauthenticatienced时,它仍然是错误的。
    

其他人提到的,对状态更新进行了反应,以优化性能,这意味着
javascript reactjs node.js authentication
2个回答
0
投票
运行“异步”(尽管这不是一个有希望的退货功能)。

如果您不使用诸如

useSWR

之类的客户端缓存库,那么请通过React文档,正确的方法是在

useEffect()
中进行数据获取。只需确保有一个ignore标志即可避免潜在的比赛条件,并为null
状态增加了何时仍在加载的状态(又称您决定允许用户访问或导航它们之前)。最后,您的组件应该看起来像这样:
import React, { useState, useEffect } from "react";
import { Navigate } from "react-router-dom";
import Cookies from "js-cookie";
import axios from "axios";

function PrivateRoute({ children }) {
    const [isAuthenticated, setIsAuthenticated] = useState(null);
    const sessionId = Cookies.get("sessionId");

    useEffect(() => {
        let ignore = false;
        async function checkAuth() {
            try {
                axios.defaults.withCredentials = true;
                if (sessionId) {
                    const response = await axios.get("http://127.0.0.1:5000/session", { params: { sessionId } });
                    const isSuccess = response.status === 200;
                    if (!ignore) {
                        console.log(isSuccess ? "authenticated" : "unauthenticated");
                        setIsAuthenticated(isSuccess);
                    }
                }
            } catch (err) {
                if (!ignore) {
                    console.error(err);
                    setIsAuthenticated(false);
                }
            }
        }

        checkAuth();
        return () => { ignore = true; };
    }, [sessionId]);

    console.log(isAuthenticated);

    if (isAuthenticated === null) return "Loading...";

    return isAuthenticated ? children : <Navigate to="/login" />;
}

export default PrivateRoute;

function PrivateRoute({ children }) { const [isAuthenticated, setIsAuthenticated] = useState(false); async function checkAuth() { // api call and set isAuthenticated } useEffect(() => { checkAuth(); }, []); // should expecte this line to run twice // false for the first time as the component first mounted (1st render) // ture or false for the second time when the api call is completed (2nd render) console.log(isAuthenticated); return isAuthenticated ? children : <Navigate to="/login" />; } export default PrivateRoute;


0
投票
代码中的CheckAuth是一个异步函数,因此在
console.log(isAuthenticated);
    之前运行
  1. setIsAuthenticated(true);

    设置功能仅更新下一个渲染的状态变量。如果您在调用设置功能后读取状态变量,则在调用之前仍将获取屏幕上的旧值。 
    doc

  2. 使用usefect而不是直接调用该函数。 doc

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.