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

如何优化React Query条件调用多查询的冗余代码

优化React Query多实例冗余代码的几种方案

针对你当前的代码冗余问题,除了条件设置请求URL,还有以下几种优化思路,最终都能实现只返回一组{data, isLoading, isError}状态:


1. 动态配置单个useQuery实例

直接根据路由参数动态生成queryKey、queryFn以及数据转换逻辑,只用一个useQuery实例就能覆盖两种场景,彻底消除重复代码:

const { language, difficulty, source } = props.match.params;

const { data, isLoading, isError } = useQuery({
  // 动态生成唯一查询键,区分不同source和参数
  queryKey: [`test-${source}-${language}`, difficulty],
  queryFn: async () => {
    let response;
    if (source === "api") {
      response = await fetch(
        `${BASE_URL}${API_URLS.GET_QUIZ}/?languages=${language}&level=${difficulty}`
      );
    } else if (source === "intern") {
      response = await fetch(
        `${BASE_URL}${API_URLS.TEST}/${language}`
      );
    }
    const rawData = await response.json();
    // 针对intern场景做数据转换
    return source === "intern" ? rawData?.questions || [] : rawData;
  },
  // 参数变化时queryKey自动触发重查,无需手动控制enabled
  enabled: true,
});

// 直接使用useQuery返回的状态,无需额外useEffect同步

这个方案的优势是完全复用单个useQuery的生命周期,逻辑紧凑,路由参数变化时自动触发重新查询,省去了额外的状态同步代码。


2. 使用useQueries合并请求并映射结果

如果需要保留两个请求的独立配置(比如后续可能需要同时启用),可以用useQueries批量管理多个查询,再通过逻辑映射出统一状态:

const { language, difficulty, source } = props.match.params;

const queries = useQueries({
  queries: [
    {
      queryKey: [`test-api-${language}`, difficulty],
      queryFn: () => fetch(
        `${BASE_URL}${API_URLS.GET_QUIZ}/?languages=${language}&level=${difficulty}`
      ).then(res => res.json()),
      enabled: source === "api",
    },
    {
      queryKey: [`test-intern-${language}`],
      queryFn: () => fetch(
        `${BASE_URL}${API_URLS.TEST}/${language}`
      ).then(res => res.json()),
      enabled: source === "intern",
    },
  ],
});

// 映射出统一的对外状态
const activeQuery = source === "api" ? queries[0] : queries[1];
const data = source === "intern" ? activeQuery.data?.questions || [] : activeQuery.data;
const isLoading = activeQuery.isLoading;
const isError = activeQuery.isError;

这个方案适合需要同时维护多查询配置,但又要对外暴露统一状态的场景,灵活性更高。


3. 封装自定义Hook抽离逻辑

把整个查询逻辑封装成自定义Hook,组件只需要传入路由参数,直接拿到统一状态,让组件代码更干净:

// 自定义Hook:useTestData.js
export const useTestData = ({ language, difficulty, source }) => {
  return useQuery({
    queryKey: [`test-${source}-${language}`, difficulty],
    queryFn: async () => {
      let response;
      if (source === "api") {
        response = await fetch(
          `${BASE_URL}${API_URLS.GET_QUIZ}/?languages=${language}&level=${difficulty}`
        );
      } else if (source === "intern") {
        response = await fetch(
          `${BASE_URL}${API_URLS.TEST}/${language}`
        );
      }
      const rawData = await response.json();
      return source === "intern" ? rawData?.questions || [] : rawData;
    },
    enabled: !!source,
  });
};

// 组件中使用
const { language, difficulty, source } = props.match.params;
const { data, isLoading, isError } = useTestData({ language, difficulty, source });

这种方式把业务逻辑从组件中抽离,不仅让组件更简洁,还方便后续在其他组件复用这段查询逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:20:30