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

如何在Axios拦截器中使用useSelector?Hook调用报错求助

解决Axios拦截器中使用useSelector的Hook调用错误

错误原因

useSelector 是React Hook,必须满足两个核心规则:

  • 只能在函数组件或自定义Hook的顶层作用域调用
  • 不能在普通工具函数、循环、条件判断中调用

你现在在普通函数 axiosRequest 里直接使用 useSelector,违反了Hook规则,所以触发 Invalid hook call 错误。

解决方案一:直接访问Redux Store实例

如果你的Redux Store是单独创建并导出的(比如store.ts中导出了store对象),可以直接调用store.getState()获取状态,无需使用Hook:

import store from './path/to/your/store'; // 导入你的Redux Store实例
import { currentUserToken } from './path/to/your/selectors';

function axiosRequest(request: AxiosRequestConfig): AxiosRequestConfig | Promise<AxiosRequestConfig> {
  const state = store.getState();
  const currentToken = currentUserToken(state); // 直接调用selector函数传入state

  request.headers["X-Auth-token"] = currentToken;
  return request;
}

这种方式简单直接,适合在非组件环境中获取Redux状态。

解决方案二:在组件中动态更新Axios默认Headers

将token的获取放在React组件中,利用useSelector监听token变化,实时更新Axios实例的默认请求头:

// 根组件(如App.tsx)
import { useSelector, useEffect } from 'react-redux';
import { instance } from './path/to/your/axios-instance';
import { currentUserToken } from './path/to/your/selectors';

function App() {
  const currentToken = useSelector(currentUserToken);

  // 每次token变化时更新Axios默认请求头
  useEffect(() => {
    instance.defaults.headers.common['X-Auth-token'] = currentToken;
  }, [currentToken, instance]);

  return (
    // 你的组件内容
  );
}

此时拦截器无需再处理token,直接返回请求即可:

function axiosRequest(request: AxiosRequestConfig): AxiosRequestConfig | Promise<AxiosRequestConfig> {
  return request;
}

这种方式更贴合React数据流,将状态管理逻辑限制在组件内部。

解决方案三:用自定义Hook初始化拦截器

创建自定义Hook,在Hook内部使用useSelector获取token,并动态添加/移除拦截器,完全符合Hook规则:

import { useSelector, useEffect } from 'react-redux';
import { AxiosInstance } from 'axios';
import { currentUserToken } from './path/to/your/selectors';

function useAxiosInterceptor(instance: AxiosInstance) {
  const currentToken = useSelector(currentUserToken);

  useEffect(() => {
    // 添加请求拦截器
    const interceptorId = instance.interceptors.request.use(
      (request) => {
        request.headers["X-Auth-token"] = currentToken;
        return request;
      },
      (error) => Promise.reject(error?.message || error)
    );

    // 组件卸载时移除拦截器,避免内存泄漏
    return () => {
      instance.interceptors.request.eject(interceptorId);
    };
  }, [instance, currentToken]);
}

然后在根组件中调用这个Hook:

// App.tsx
import { instance } from './path/to/your/axios-instance';
import { useAxiosInterceptor } from './path/to/your/hook';

function App() {
  useAxiosInterceptor(instance);

  return (
    // 你的组件内容
  );
}

这种方式既符合Hook规则,又能保证token变化时拦截器自动更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:35:15