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

React Context无法保存AuthContext状态,页面刷新后登录态丢失

解决React中JWT登录状态刷新后重置的问题

问题根源

React组件的useState状态仅保存在内存中,页面刷新、组件重新挂载时会重置为初始值,导致登录状态丢失。你当前的AuthProvider初始化auth为null,没有从持久化存储中读取之前保存的登录信息。

解决方案

将登录状态持久化到浏览器的localStorage(或sessionStorage,前者关闭浏览器仍保留,后者关闭即清除),在AuthProvider初始化时读取存储的信息,更新状态时同步更新存储。


1. 更新authProvider.js

import { createContext, useState, useEffect } from "react";

const AuthContext = createContext({});

export const AuthProvider = ({ children }) => {
    // 初始化时从localStorage读取保存的auth数据
    const [auth, setAuth] = useState(() => {
        const savedAuth = localStorage.getItem('auth');
        return savedAuth ? JSON.parse(savedAuth) : null;
    });

    // 当auth状态变化时,同步保存到localStorage
    useEffect(() => {
        if (auth) {
            localStorage.setItem('auth', JSON.stringify(auth));
        } else {
            localStorage.removeItem('auth');
        }
    }, [auth]);

    console.log(auth);

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

export default AuthContext;

2. 优化Login组件(修正异步状态打印问题)

注意setAuth是异步操作,你当前代码里的console.log(auth)会打印旧值,属于正常现象。可以优化请求错误处理逻辑:

const handleSubmit = (e) => {
    e.preventDefault();
    fetch('http://localhost:4000/api/auth/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ email, password })
    })
    .then(res => {
        if (!res.ok) throw new Error('登录失败,请检查账号密码');
        return res.json();
    })
    .then(data => {
        // 建议不要存储password,减少安全风险
        setAuth({ email, token: data.token, refreshToken: data.refreshToken, role: data.role });
        navigate(from, { replace: true });
    })
    .catch(err => {
        document.querySelector('#error').innerHTML = err.message;
    });
}

3. 可选:添加登出功能

在需要登出的组件中调用:

import useAuth from '../hooks/useAuth';
import { useNavigate } from 'react-router-dom';

const SomeComponent = () => {
    const { setAuth } = useAuth();
    const navigate = useNavigate();

    const handleLogout = () => {
        setAuth(null);
        navigate('/login');
    }

    return <button onClick={handleLogout}>退出登录</button>
}

额外注意事项

  • 安全风险:不要将password存储到localStorage,因为它是明文存储的,易受XSS攻击。仅保留必要的登录信息(如token、角色、邮箱)即可。
  • Token过期:后续可添加token有效性校验逻辑,初始化时检查token是否过期,无效则清除状态并跳转登录页。
  • 更高安全性:若对安全性要求高,可配合后端使用HttpOnly Cookie存储token,避免前端直接操作敏感信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:09:29