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

如何在RTK Query的queryFn中结合transformResponse与createEntityAdapter?

解决方案

错误原因分析

  1. transformResponse不可用:使用queryFn自定义查询逻辑时,RTK Query不支持同时配置transformResponse,这是第二个类型错误的直接原因。
  2. 返回类型不匹配:端点声明返回类型为EntityState<Workout, string>,但queryFn实际返回的是Workout[]数组,类型不匹配导致第一个TypeScript错误。

修正后的代码

// 假设你已提前定义EntityAdapter和初始状态
const workoutsAdapter = createEntityAdapter<Workout>({
  selectId: (workout) => workout.id,
});

const initialState = workoutsAdapter.getInitialState();

export const workoutApi = createApi({
  baseQuery: fakeBaseQuery<WorkoutError>(),
  endpoints: (build) => ({
    getWorkouts: build.query<EntityState<Workout, string>, void>({
      queryFn: async () => {
        try {
          const workoutsSnapshot = await firestore().collection('workouts').get();
          // 转换Firestore文档为Workout数组
          const workoutsData = workoutsSnapshot.docs.map((doc) => ({
            id: doc.id,
            name: doc.data().name,
            date: format(doc.data().date.toDate(), 'MM/dd/yyyy'),
          } as Workout)); // 断言为Workout类型,确保类型匹配

          // 用EntityAdapter将数组转换为EntityState
          const entityState = workoutsAdapter.setAll(initialState, workoutsData);
          return { data: entityState };
        } catch (e) {
          return {
            error: {
              status: 500,
              message: (e as Error).message,
            },
          };
        }
      },
      // 移除transformResponse,queryFn模式下不支持该配置
    }),
  }),
});

关键改动说明

  • 移除transformResponse:queryFn模式下,数据转换逻辑需直接写在queryFn内部,无法依赖transformResponse。
  • 在queryFn内转换为EntityState:获取原始数据数组后,直接调用workoutsAdapter.setAll()将其转换为符合要求的EntityState结构,再作为data返回,解决类型不匹配问题。
  • 类型断言:通过as Workout确保转换后的每个对象符合Workout类型定义,避免TypeScript隐式类型推断错误。

额外提示

  • 确保Workout类型定义与Firestore返回字段完全匹配,示例:
    interface Workout {
      id: string;
      name: string;
      date: string;
    }
    
  • 组件中可通过workoutsAdapter.getSelectors()便捷获取EntityState中的数据,示例:
    const { selectAll, selectById } = workoutsAdapter.getSelectors(
      (state) => state.workoutsApi // 对应你的API切片状态
    );
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:08:22