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

ReactJS页面刷新时Auth Context丢失问题排查求助

问题分析与解决方案

核心问题

  1. 页面刷新时,AuthProvider初始化的auth是空对象,而getAccountInfo是异步请求——RequireAuth会先完成渲染,此时auth.user还未被赋值,直接触发重定向到登录页。
  2. 需确认api.getAccountInfo()是否正确携带localStorage中的token,若请求未带有效凭证,后端会返回未授权,导致auth始终为空。

解决方案

1. 给AuthProvider添加加载状态,避免过早判断授权

修改src/context/AuthProvider.js,增加加载状态,确保用户信息加载完成前不做授权判断:

import { useEffect, useState, createContext } from 'react';
import api from '../helper/api';

const AuthContext = createContext({});

function AuthProvider({ children }) {
    const [auth, setAuth] = useState({});
    const [isLoading, setIsLoading] = useState(true); // 新增加载状态

    useEffect(() => {
        const apiHelper = new api();
        apiHelper.getAccountInfo()
            .then((response) => {
                setAuth(response.data);
            })
            .catch(() => {
                // 请求失败时清空授权信息和token
                setAuth({});
                localStorage.removeItem('token');
            })
            .finally(() => {
                setIsLoading(false); // 请求完成后结束加载
            });
    }, []);

    return (
        <AuthContext.Provider value={{ auth, setAuth, isLoading }}>
            {children}
        </AuthContext.Provider>
    );
}

export { AuthContext, AuthProvider };

2. 修改RequireAuth组件,等待加载完成再判断

修改src/components/RequireAuth/index.js,先等待加载完成,再根据授权状态处理跳转:

import { useLocation, Navigate, Outlet } from 'react-router-dom';
import useAuth from '../../hooks/useAuth';
import LoadingSpinner from '../LoadingSpinner'; // 用你自己的加载组件

function RequireAuth() {
    const { auth, isLoading } = useAuth();
    const location = useLocation();

    // 加载中时显示加载组件,避免页面闪烁或错误跳转
    if (isLoading) {
        return <LoadingSpinner />;
    }

    return auth?.user ? (
        <Outlet />
    ) : (
        <Navigate to={{ pathname: '/', state: { from: location } }} replace />
    );
}

export default RequireAuth;

3. 确保API请求携带token

检查你的api工具类,确保getAccountInfo请求时在请求头里携带localStorage中的token,示例:

class api {
    getAccountInfo() {
        const token = localStorage.getItem('token');
        return fetch('/api/account-info', {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        }).then(res => res.json());
    }

    // 其他API方法...
}

如果token无效/过期,后端返回错误时,AuthProvider会自动清空授权信息,正确跳转到登录页。

4. 优化登录逻辑(可选)

在Login组件的登录成功回调中,先存入token再更新Auth状态,确保后续刷新时API能拿到有效凭证:

// Login组件submitForm方法中调整顺序
localStorage.setItem('token', response.data.token);
setAuth({ user: response.data.user });
navigate('/dashboard');

内容的提问来源于stack exchange,提问作者namln-hust

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:35:17