如何在Axios实例中使用React状态中的Token?
解决方法:
问题根源
useSelector是React Hook,必须遵循Hook规则——只能在函数组件或自定义Hook的顶层调用。你在普通JS模块(Axios实例创建文件)中调用它,违反了这个规则,所以抛出错误。
最优解决方案:使用Axios请求拦截器动态注入Token
通过Axios拦截器,每次发送请求前从Redux Store中获取最新的Token并设置到请求头,既符合规则又能保证Token始终是最新状态。
步骤1:确保Redux Store实例可导出
在你的Store配置文件(比如store.js)中导出创建好的Store实例:
import { configureStore } from '@reduxjs/toolkit'; import authReducer from './path/to/authSlice'; // 导出Store实例 export const store = configureStore({ reducer: { auth: authReducer, }, });
步骤2:修改Axios实例,添加请求拦截器
在Axios实例文件中,导入Store并通过store.getState()获取Token,在拦截器中动态设置请求头:
import axios from 'axios'; import { store } from './store'; // 导入刚才导出的Store const api = axios.create({ baseURL: baseUrl, // 确保baseUrl已正确定义 }); // 添加请求拦截器 api.interceptors.request.use( (config) => { // 从Store中获取最新的Token const token = store.getState().auth.token; if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { // 处理请求错误 return Promise.reject(error); } ); export default api;
其他可选方案
从本地存储(LocalStorage/SessionStorage)读取Token:
如果你的Token同时存在本地存储中,可以直接在拦截器中读取:api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; });注意:需要确保Redux中的Token更新时同步到本地存储,避免Token不一致。
在自定义Hook中创建Axios实例(组件内使用):
如果你只在React组件内使用Axios,可以通过自定义Hook创建实例并注入Token,利用useMemo缓存实例:import axios from 'axios'; import { useSelector } from 'react-redux'; import { useMemo } from 'react'; export const useApi = () => { const token = useSelector((state) => state.auth.token); const api = useMemo(() => { return axios.create({ baseURL: baseUrl, headers: token ? { Authorization: `Bearer ${token}` } : {}, }); }, [token]); return api; };这种方式仅适用于组件内部调用,灵活性不如拦截器方案。
内容的提问来源于stack exchange,提问作者zskiredj
相关产品推荐
相关产品推荐

