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

使用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: () => ({})
});

可能的排查方向

  1. 互斥锁逻辑问题
    • 检查async-mutex包是否正确安装、版本是否适配RTK Query
    • 移除初始的await mutex.waitForUnlock(),仅在锁存在时执行等待逻辑,避免不必要的请求阻塞
  2. 请求凭证缺失
    • 原生fetchBaseQuery可能默认携带请求凭证,自定义baseQuery仅在刷新请求时设置了credentials: "include",初始请求未传递该参数导致认证失败,修改baseQuery初始化代码:
      const baseQuery = fetchBaseQuery({
        baseUrl,
        credentials: "include"
      });
      
  3. 错误判断逻辑偏差
    • 打印result.error完整结构,确认错误数据格式是否与(result.error?.data as any)?.message === "You are not logged in"的判断逻辑匹配,避免类型断言导致的判断失效
  4. 环境变量读取问题
    • 打印customFetchBase中的baseUrl,确认是否与正常配置中的process.env.BASE_URL一致,避免环境变量读取异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:05:46