使用RTK Query自定义customFetchBase刷新Token时出现getState未定义错误
问题排查:RTK Query自定义baseQuery导致请求异常
错误截图

排查过程
- 参考RTK Query官方自动重授权自定义查询逻辑实现
- 参考第三方刷新令牌认证教程
- 查阅多个相关仓库代码
- 以上尝试均未解决问题
异常配置代码
apiSlice.ts
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import customFetchBase from "./customFetchBase"; export const apiSlice = createApi({ reducerPath: "api", baseQuery: customFetchBase, tagTypes: ["User", "Interests"], endpoints: () => ({}) });
customFetchBase.ts
import { BaseQueryFn, FetchArgs, fetchBaseQuery, FetchBaseQueryError } from "@reduxjs/toolkit/query"; import { Mutex } from "async-mutex"; const baseUrl = `${process.env.BASE_URL}`; // 创建互斥锁 const mutex = new Mutex(); const baseQuery = fetchBaseQuery({ baseUrl }); const customFetchBase: BaseQueryFn< string | FetchArgs, unknown, FetchBaseQueryError > = async (args, api, extraOptions) => { // 等待互斥锁释放 await mutex.waitForUnlock(); let result = await baseQuery(args, api, extraOptions); console.log("-> result", result); if ((result.error?.data as any)?.message === "You are not logged in") { if (!mutex.isLocked()) { const release = await mutex.acquire(); console.log("-> release", release); try { const refreshResult = await baseQuery( { credentials: "include", url: "oauth/token" }, api, extraOptions ); console.log("-> refreshResult", refreshResult); if (refreshResult.data) { // 重试初始请求 result = await baseQuery(args, api, extraOptions); } /* else { api.dispatch(logout()); window.location.href = "/login"; } */ } finally { // 释放互斥锁 release(); } } else { // 等待互斥锁释放后重试 await mutex.waitForUnlock(); result = await baseQuery(args, api, extraOptions); } } return result; }; export default customFetchBase;
正常工作的配置
export const apiSlice = createApi({ reducerPath: "api", baseQuery: fetchBaseQuery({ baseUrl: process.env.BASE_URL }) /// ----> 与异常配置的区别所在 tagTypes: ["User", "Interests"], endpoints: () => ({}) });
可能的排查方向
- 互斥锁逻辑问题
- 检查
async-mutex包是否正确安装、版本是否适配RTK Query - 移除初始的
await mutex.waitForUnlock(),仅在锁存在时执行等待逻辑,避免不必要的请求阻塞
- 检查
- 请求凭证缺失
- 原生
fetchBaseQuery可能默认携带请求凭证,自定义baseQuery仅在刷新请求时设置了credentials: "include",初始请求未传递该参数导致认证失败,修改baseQuery初始化代码:const baseQuery = fetchBaseQuery({ baseUrl, credentials: "include" });
- 原生
- 错误判断逻辑偏差
- 打印
result.error完整结构,确认错误数据格式是否与(result.error?.data as any)?.message === "You are not logged in"的判断逻辑匹配,避免类型断言导致的判断失效
- 打印
- 环境变量读取问题
- 打印
customFetchBase中的baseUrl,确认是否与正常配置中的process.env.BASE_URL一致,避免环境变量读取异常
- 打印
内容的提问来源于stack exchange,提问作者Legeo
相关产品推荐
相关产品推荐

