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

RTK Query中如何在transformResponse复用其他查询缓存?

RTK Query 顺序查询并复用缓存数据的正确实现方式

你的原思路不可行,因为transformResponse函数只能拿到当前查询的响应、元数据和参数,无法直接访问getFirst查询的缓存数据,没法在里面直接用第一个查询的结果做转换。下面提供两种可行的解决方案:

方案一:组件层面控制查询顺序(推荐)

在组件中先获取第一个查询的数据,拿到结果后再触发第二个查询,把第一个查询的数据作为参数传给第二个查询,这样就能在transformResponse里直接使用。

修改API定义

const myApi = createApi({
  reducerPath: 'myApi',
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  endpoints: (builder) => ({
    getFirst: builder.query({
      query: () => '/getFirst',
    }),
    getSecond: builder.query({
      // 接收第一个查询的数据作为参数(仅作为依赖标识,无需在请求中使用)
      query: (firstData) => '/getSecond',
      transformResponse: (response, meta, firstData) => {
        // 使用firstData转换响应数据
        const transformedConfig = response.map(item => ({
          ...item,
          // 用firstData中的字段增强配置
          extraInfo: firstData.find(data => data.id === item.id)?.info
        }));
        return transformedConfig;
      },
    }),
  }),
});

export const { useGetFirstQuery, useGetSecondQuery } = myApi;

组件中使用

function MyComponent() {
  // 先获取第一个查询的数据
  const { data: firstData, isLoading: firstLoading } = useGetFirstQuery();
  
  // 仅当firstData存在时,触发第二个查询
  const { data: secondData, isLoading: secondLoading } = useGetSecondQuery(firstData, {
    skip: !firstData // 无firstData时跳过查询
  });

  if (firstLoading || secondLoading) return <div>加载中...</div>;
  if (!firstData || !secondData) return <div>加载失败</div>;

  return <div>{/* 渲染处理后的数据 */}</div>;
}

方案二:API层通过queryFn处理顺序查询

如果不想在组件里处理顺序逻辑,可以用queryFn自定义查询流程,在里面先尝试获取第一个查询的缓存,缓存不存在则主动发起第一个查询,再请求第二个并完成数据转换。

const myApi = createApi({
  reducerPath: 'myApi',
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  endpoints: (builder) => ({
    getFirst: builder.query({
      query: () => '/getFirst',
    }),
    getSecond: builder.query({
      queryFn: async (_, { getState, dispatch }) => {
        // 尝试从缓存获取getFirst的数据
        const firstCache = myApi.endpoints.getFirst.select()(getState());
        let firstData = firstCache.data;

        // 缓存无数据时,主动发起getFirst查询
        if (!firstData) {
          const firstResult = await dispatch(myApi.endpoints.getFirst.initiate());
          if (firstResult.isError) {
            return { error: firstResult.error };
          }
          firstData = firstResult.data;
        }

        // 发起第二个查询
        const secondResult = await fetchBaseQuery({ baseUrl: '/' })({ url: '/getSecond' });
        if (secondResult.error) {
          return { error: secondResult.error };
        }

        // 用firstData转换第二个查询的响应
        const transformedData = secondResult.data.map(item => ({
          ...item,
          extraInfo: firstData.find(data => data.id === item.id)?.info
        }));

        return { data: transformedData };
      },
    }),
  }),
});

组件中使用

这种方式下,组件只需调用第二个查询,内部会自动处理第一个查询的依赖:

function MyComponent() {
  const { data: secondData, isLoading } = useGetSecondQuery();

  if (isLoading) return <div>加载中...</div>;
  if (!secondData) return <div>加载失败</div>;

  return <div>{/* 渲染处理后的数据 */}</div>;
}

总结

  • 原思路的核心问题是transformResponse无法跨查询访问缓存,必须通过参数传递或在queryFn中主动获取缓存/发起查询解决。
  • 方案一更直观,组件逻辑清晰,适合大多数场景;方案二把逻辑封装在API层,组件更简洁,但需要处理缓存和错误的细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:35:08