You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Node应用中isAuthenticated认证状态无法更新问题求助

问题:受保护路由认证状态更新异常

我正在实现用户认证功能,检查用户是否持有访问受保护路由所需的正确令牌,但useAuth文件中的useEffect无法正确更新isAuthenticated的状态,导致受保护路由总是跳转到登录页面。

现有代码

useAuth.jsx

// useAuth.jsx file
import { useState, useEffect } from "react";
import axios from "axios";

const useAuth = () => {
    const [isAuthenticated,setIsAuthenticated] = useState(false);
    useEffect(() =>{
        const authentication = async() => {
            const response = await axios.get("http://localhost:5000/authenticateTokens", {withCredentials: true} );
            console.log(response.data.success);
            setIsAuthenticated(response.data.success);
        }
        authentication();
    },[]);
    console.log(isAuthenticated)
    return { isAuthenticated, setIsAuthenticated };
};

export default useAuth;

注:上述axios请求会返回包含true或false的JSON数据,格式符合预期。

PrivateRoutes.jsx

import { Outlet, Navigate } from "react-router-dom";
import useAuth from './useAuth';


const PrivateRoutes = ({component: component, ...rest}) => {
    const {isAuthenticated} = useAuth();
    return(
        // 条件判断:认证通过则渲染子组件,否则跳转到登录页
        isAuthenticated ? <Outlet/> : <Navigate to = "/signin"/>
    )
}

export default PrivateRoutes;

问题原因分析

  1. 异步时序问题:isAuthenticated初始值为false,而useEffect中的axios请求是异步操作。PrivateRoutes第一次渲染时,认证请求还未完成,此时isAuthenticated仍为初始值,直接触发跳转。等请求完成后状态更新,但组件已完成重定向,不会再重新判断。
  2. 缺少加载状态:没有在认证请求过程中设置加载状态,导致组件在请求未完成时就执行了跳转逻辑。
  3. 无错误处理:如果axios请求失败(比如网络问题、后端报错),setIsAuthenticated不会被调用,状态会一直停留在初始的false。

解决方案

修改useAuth.jsx,添加加载状态与错误处理

// useAuth.jsx file
import { useState, useEffect } from "react";
import axios from "axios";

const useAuth = () => {
    const [isAuthenticated, setIsAuthenticated] = useState(false);
    // 添加加载状态,标记认证请求是否完成
    const [isLoading, setIsLoading] = useState(true);

    useEffect(() => {
        const authentication = async () => {
            try {
                const response = await axios.get("http://localhost:5000/authenticateTokens", { withCredentials: true });
                setIsAuthenticated(response.data.success);
            } catch (error) {
                // 请求失败时默认设为未认证,并打印错误信息
                setIsAuthenticated(false);
                console.error("认证请求失败:", error);
            } finally {
                // 请求完成(无论成功失败),结束加载状态
                setIsLoading(false);
            }
        };
        authentication();
    }, []);

    return { isAuthenticated, isLoading, setIsAuthenticated };
};

export default useAuth;

修改PrivateRoutes.jsx,等待认证结果后再执行跳转逻辑

import { Outlet, Navigate } from "react-router-dom";
import useAuth from './useAuth';

const PrivateRoutes = () => {
    const { isAuthenticated, isLoading } = useAuth();

    // 加载中时显示提示(也可以返回null或自定义加载组件)
    if (isLoading) {
        return <div>正在验证身份...</div>;
    }

    return isAuthenticated ? <Outlet /> : <Navigate to="/signin" />;
};

export default PrivateRoutes;

修改说明

  • 新增isLoading状态,确保在认证请求完成前不执行跳转逻辑,避免因异步时序问题导致的错误跳转。
  • 为axios请求添加try/catch捕获异常,处理请求失败的场景,保证状态始终能被正确更新。
  • 简化了PrivateRoutes的参数,因为原代码中的component和rest参数未被使用。

内容的提问来源于stack exchange,提问作者Dylan Bose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:37:40