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
相关产品推荐
相关产品推荐

