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

为何将axiosPrivate置于自定义Hook内时Axios拦截器有时失效?

Axios拦截器在自定义Hook内部创建实例时部分失效的原因

问题背景

原本将Axios实例axiosPrivate定义在自定义Hook外部时,拦截器工作正常:

import axios from 'axios';
import { useDispatch } from 'react-redux';

const axiosPrivate = axios.create({
    baseURL: 'http://localhost:8080'
});

export default useAxiosPrivate = () => {
    const dispatch = useDispatch();

    useEffect(() => {
        const responseIntercept = axiosPrivate.interceptors.response.use(
            response => response,
            async (error) => {
                const prevRequest = error?.config;
                if (error.response?.status === 401 && error.response.data?.code === 'AccessTokenExpired' && !prevRequest.sent) {
                    prevRequest.sent = true;
                    const { refreshToken } = await getData();
                    return axios.post('http://localhost:8080/auth/refresh-token', { refreshToken })
                        .then(async (_) => {
                            return axiosPrivate(prevRequest);
                        })
                        .catch(async (error) => {
                            dispatch(login({ name: '', id: '' }));
                            return Promise.reject(error);
                        });
                }
                return Promise.reject(error);
            }
        );

        return () => {
            axiosPrivate.interceptors.response.eject(responseIntercept);
        }
    }, [])

    return axiosPrivate;
}

之后尝试将axiosPrivate移至自定义Hook内部:

export default useAxiosPrivate = () => {
    const axiosPrivate = axios.create({
        baseURL: 'localhost:8080'
    });

    const dispatch = useDispatch();
    // 后续拦截器逻辑同原代码...
}

此时出现部分组件中拦截器正常工作,另一部分组件中拦截器完全失效的现象。

原因解析

  • 每次调用Hook都会生成全新的Axios实例:把axiosPrivate放在Hook内部后,每个调用useAxiosPrivate的组件都会得到一个独立的Axios实例。拦截器是绑定在单个实例上的,只有那些在useEffect(拦截器挂载逻辑在这里)执行完成后才发起请求的组件,其对应的实例拦截器才会生效;如果组件在useEffect执行前就发起请求,此时拦截器还没挂载到这个新实例上,就会出现拦截器“失效”的情况。
  • 组件渲染时机导致拦截器挂载时机不一致:不同组件的渲染顺序和生命周期阶段有差异,有些组件可能在Hook的useEffect执行前就调用Axios实例发请求,这时实例上还没有绑定拦截器,请求直接发出,不会触发拦截逻辑;而另一些组件在useEffect执行完成后才发请求,拦截器已经挂载,所以能正常工作。
  • 原代码的核心优势:原代码中axiosPrivate是全局单例,所有组件共享同一个实例,拦截器挂载后所有请求都会走这个实例的拦截逻辑,不存在挂载时机不一致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:33:18