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

React中useEffect钩子状态异常及JWT令牌刷新丢失问题

问题解决思路

你的核心问题是页面刷新时,useEffect 会在 getUser 异步请求完成前就执行 handleLogout,把 localStorage 里的 token 删掉,导致后续认证失败进入恶性循环。下面是具体的修复方案:

修复步骤

1. 调整导航栏的 useEffect 逻辑

不要在初始渲染时直接判断 User 是否为空就触发登出,应该先检查本地是否存在 token,再等待 getUser 请求完成后处理状态:

// part of navbar.js
const { User, getUser } = useContext(NoteContext);
const handleLogout = () => {
    localStorage.removeItem("token");
    navigate("/login");
};

useEffect(() => {
  const token = localStorage.getItem("token");
  // 无token直接登出
  if (!token) {
    handleLogout();
    return;
  }
  // 有token则等待用户信息请求完成后再判断状态
  const fetchAndCheckUser = async () => {
    await getUser();
    // 请求完成后若仍无用户信息,说明token无效,执行登出
    if (User === "") {
      handleLogout();
    }
  };
  fetchAndCheckUser();
}, [User, getUser, navigate]);

2. 优化Context中的getUser函数

把token有效性判断和清理逻辑整合到函数内部,减少外部重复判断:

// part of context
const [User, setUser] = useState("");
const getUser = async () => {
  const token = localStorage.getItem("token");
  // 先检查token是否存在
  if (!token) {
    setUser("");
    return;
  }
  const response = await fetch(`${host}/api/auth/getuser`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      "auth-token": token,
    },
  });
  if (response.status === 200) {
    const json = await response.json();
    setUser(json.user.email);
  } else {
    // token无效时直接清空本地存储和用户状态
    localStorage.removeItem("token");
    setUser("");
  }
};

关键逻辑说明

  • 优先检查本地token是否存在,避免无意义的请求和误删token
  • 用异步函数包裹getUser,等待请求完成后再判断用户状态,解决异步请求未完成就触发登出的问题
  • 给useEffect补充完整的依赖数组,确保状态更新时逻辑能重新执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:30:18