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

React中localStorage存储token后首次请求API返回401错误如何解决

问题根源

你遇到的问题核心原因有3个:

  • React的setToken是异步状态更新方法,调用后立刻读取token变量,拿到的还是当前渲染周期的旧值(首次加载时是初始值null),所以第一次写入localStorage的内容本身就是null
  • Apihelper.js里的token是模块初始化时一次性从localStorage读取的,后续localStorage更新后,这里的headers不会自动刷新
  • token还没成功写入localStorage时就触发了重定向,跳转到Chatroom发起请求时自然拿不到有效token

修复方案

1. 修改Home.js

直接用从URL参数拿到的原始token值写入localStorage,不要依赖异步更新的state,确认写入完成后再触发重定向:

useEffect(() => {
  const queryParams = new URLSearchParams(window.location.search);
  const rawToken = queryParams.get("token");
  // 先判断token存在再执行存储和重定向逻辑
  if (rawToken) {
    // 直接用刚拿到的token存localStorage,不走state的异步更新
    localStorage.setItem('token', rawToken)
    setToken(rawToken)
    setRedirect(true)
  }
}, []);

if (redirect) {
    return (
      <Redirect
        to={{
          pathname: "/chatroom",
          // 这里如果需要传递token相关参数,直接从localStorage取或者用rawToken,不要用未更新的state
          state: { token: localStorage.getItem('token') },
        }}
      />
    );
  }
return ""; 

2. 修改Apihelper.js

把token读取逻辑放到请求发起时动态执行,不要在模块顶层一次性读取,保证每次请求都能拿到最新的localStorage值:

// 删掉顶层的token、headers固定定义,改为请求时动态生成
export const initiateChat = async (data) => {
  const token = localStorage.getItem("token");
  const headers = {
    Authorization: `Bearer ${token}`,
  };
  return await axios.post(`${API}/room/initiate`, data, {
    headers,
 });
}

3. 可选优化Chatroom.js

增加token存在性判断,避免无意义的无效请求:

import { initiateChat } from "../Apihelper";

const Chatroom = (props) => {

useEffect(() => {
    // 先判断本地有token再发起请求
    if (localStorage.getItem("token")) {
      setLoading(true);
      initiateChat(user, props.location.state).then(({data}) => setUsers(data))
    }
}, []);

}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:39:04