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

RTK Query:如何转换失败请求响应及解决data命名冲突

问题1:统一处理失败请求的响应格式

RTK Query 的 transformResponse 仅处理状态码 200-299 的成功响应,要对错误响应做类似转换,推荐通过自定义 baseQuery 全局统一处理,也可以针对单个接口用 transformErrorResponse。

方案1:全局自定义 baseQuery(推荐)

包装原生的 fetchBaseQuery,在请求失败时解析并重构错误对象:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { MyApiUrl } from './Constants';

const customBaseQuery = async (args, api, extraOptions) => {
  const result = await fetchBaseQuery({ baseUrl: MyApiUrl })(args, api, extraOptions);

  // 处理错误响应,提取API返回的success、message字段
  if (result.error && result.error.data) {
    const { success, message, data } = result.error.data;
    result.error = {
      ...result.error,
      success,
      message,
      data
    };
  }

  return result;
};

export const apiSlice = createApi({
  reducerPath: 'api',
  baseQuery: customBaseQuery, // 使用自定义baseQuery
  tagTypes: ['Stuff'],
  endpoints: (builder) => ({
    getStuff: builder.query({
      query: ({ name, category }) => `/Stuff/FindStuff?name=${name}&category=${category}`,
      transformResponse: (res) => res,
      providesTags: ['Stuff']
    }),
  })
});

export const { useGetStuffQuery } = apiSlice;

组件中直接从 error 对象获取字段:

const { 
  data: stuff,
  isLoading,
  isSuccess,
  isError,
  error
} = useGetStuffQuery({ name, category });

if (isError) {
  console.log(error.message, error.success);
}

方案2:单个接口用 transformErrorResponse

仅针对当前接口处理错误:

getStuff: builder.query({
  query: ({ name, category }) => `/Stuff/FindStuff?name=${name}&category=${category}`,
  transformResponse: (res) => res,
  transformErrorResponse: (error) => {
    const { success, message, data } = error.data;
    return { success, message, data };
  },
  providesTags: ['Stuff']
})

此时组件中的 error 就是转换后的对象,直接访问 error.message 即可。


问题2:解决API响应data字段与RTK Query变量冲突

在 transformResponse 中重组返回结构,把API的 data 内容提升到顶层,或重命名避免冲突:

方案1:展开API的data字段(推荐)

如果API返回的 data 是对象,直接展开到顶层,同时保留 success 和 message:

transformResponse: (res) => {
  return {
    ...res.data, // 把API的data内容展开为顶层属性
    success: res.success,
    message: res.message
  };
}

组件中直接访问:

const { data: stuff } = useGetStuffQuery({ name, category });

if (stuff) {
  console.log(stuff.blah, stuff.success, stuff.message); // 无需stuff.data.blah
}

方案2:重命名API的data字段

如果API的 data 是数组或不想展开,重命名为其他名称:

transformResponse: (res) => {
  return {
    apiData: res.data, // 重命名避免冲突
    success: res.success,
    message: res.message
  };
}

组件中访问:

const { data: stuff } = useGetStuffQuery({ name, category });

if (stuff) {
  console.log(stuff.apiData.blah, stuff.success, stuff.message);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:40:10