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

React.useEffect在axios拦截后未触发状态更新的问题咨询

解决Axios拦截器刷新Token后重发请求不更新React状态的问题

问题根源

你的响应拦截器在处理401错误时,内部发起的刷新Token请求和重发请求的Promise没有被正确返回给原请求的Promise链,导致useEffect里的.then()无法获取到重发请求的响应数据,也就不会执行setTest更新状态。

修复代码

修改响应拦截器,确保整个错误处理逻辑返回完整的Promise链:

axios_server.interceptors.response.use(null, (error) => {
    // 处理401未授权错误
    if (error.config && error.response && error.response.status === 401) {
        // 返回刷新Token的Promise,让原请求的Promise链能接住重发后的响应
        return axios_auth.post('http://localhost:4000/refresh', {}, {withCredentials: true})
            .then((res) => {
                // 更新AccessToken到Cookie
                const token = res.data.accessToken;
                cookies.set('AccessToken', token, {
                    sameSite: 'strict',
                    path: '/',
                    expires: new Date(Date.now() + 3 * 1000)
                });
                // 重发原请求
                return axios_server.request(error.config);
            })
            .catch((error2) => {
                // 刷新Token失败,直接抛出错误,可在这里跳转到登录页
                console.error('刷新Token失败:', error2);
                // 示例:跳转到登录页
                // window.location.href = '/login';
                return Promise.reject(error2);
            });
    }
    // 非401错误,直接抛出
    return Promise.reject(error);
});

更合理的处理方式

  1. 避免重复刷新Token:当多个请求同时触发401时,不要重复调用刷新Token接口,用全局变量标记刷新状态,其他请求等待刷新完成后统一重发:
let isRefreshing = false;
let requestQueue = [];

axios_server.interceptors.response.use(null, (error) => {
    if (error.config && error.response && error.response.status === 401) {
        if (!isRefreshing) {
            isRefreshing = true;
            return axios_auth.post('http://localhost:4000/refresh', {}, {withCredentials: true})
                .then((res) => {
                    const token = res.data.accessToken;
                    cookies.set('AccessToken', token, {
                        sameSite: 'strict',
                        path: '/',
                        expires: new Date(Date.now() + 3 * 1000)
                    });
                    // 重发队列里的所有请求
                    requestQueue.forEach(cb => cb(token));
                    requestQueue = [];
                    return axios_server.request(error.config);
                })
                .catch((error2) => {
                    requestQueue = [];
                    window.location.href = '/login';
                    return Promise.reject(error2);
                })
                .finally(() => {
                    isRefreshing = false;
                });
        } else {
            // 正在刷新,把当前请求加入队列,等待刷新完成后重发
            return new Promise((resolve) => {
                requestQueue.push((token) => {
                    resolve(axios_server.request(error.config));
                });
            });
        }
    }
    return Promise.reject(error);
});
  1. 完善错误处理:在React组件中添加错误捕获逻辑,处理请求失败的情况,给用户友好提示;
  2. 提前刷新Token:在请求前主动检查AccessToken的有效期,提前发起刷新请求,避免触发401错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:31:17