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

如何使用React Query在单次请求中获取多个ID对应的数据?

批量ID查询的React Query最优实现方案

针对单次GET请求获取多ID数据的场景,结合React Query的原生缓存能力,推荐以下两种递进式的最优实践:

1. 基础方案:批量查询+自动同步单ID缓存

核心思路是将批量请求作为独立查询,同时在请求成功后自动把每个返回项存入对应单ID的缓存键中——既保证批量请求的高效性,又能让后续单个ID查询直接复用缓存。

import { useQuery, QueryClient } from '@tanstack/react-query';

// 假设API请求函数:传入ID数组,返回对应对象数组
const fetchItemsByIds = async (ids: string[]) => {
  const res = await fetch(`/api/items?ids=${ids.join(',')}`);
  return res.json();
};

export const useFetchItemsByIds = (ids: string[]) => {
  const queryClient = useQueryClient();
  // 排序ID数组,确保相同ID集合不管顺序都命中同一缓存
  const sortedIds = [...ids].sort();

  return useQuery({
    queryKey: ['items', sortedIds],
    queryFn: () => fetchItemsByIds(sortedIds),
    onSuccess: (items) => {
      // 请求成功后,将每个item单独存入单ID缓存
      items.forEach(item => {
        queryClient.setQueryData(['item', item.id], item);
      });
    },
    // 空数组时不发起请求
    enabled: sortedIds.length > 0,
  });
};

方案优势

  • 批量请求的缓存会根据ID集合自动管理,重复相同ID集合的查询直接读缓存
  • 后续如果有组件用useQuery(['item', 'xxx'])查询单个数据,能直接命中缓存,无需额外请求

2. 进阶方案:按需请求(减少冗余网络请求)

如果想进一步优化,可以先筛选出缓存中不存在的ID,仅对缺失的ID发起请求,再合并缓存数据和新请求数据返回。

export const useFetchItemsByIds = (ids: string[]) => {
  const queryClient = useQueryClient();
  const sortedIds = [...ids].sort();

  // 从缓存中提取已存在的items
  const cachedItems = sortedIds
    .map(id => queryClient.getQueryData(['item', id]))
    .filter(Boolean);
  // 获取未缓存的ID
  const cachedIds = new Set(cachedItems.map(item => item.id));
  const missingIds = sortedIds.filter(id => !cachedIds.has(id));

  return useQuery({
    queryKey: ['items', sortedIds],
    queryFn: () => fetchItemsByIds(missingIds),
    // 用缓存数据作为初始值,实现即时渲染
    initialData: () => cachedItems,
    onSuccess: (newItems) => {
      // 更新新获取的item到单ID缓存
      newItems.forEach(item => {
        queryClient.setQueryData(['item', item.id], item);
      });
      // 更新批量查询的缓存为合并后的数据
      queryClient.setQueryData(['items', sortedIds], [...cachedItems, ...newItems]);
    },
    // 只有存在缺失ID时才发起请求
    enabled: missingIds.length > 0,
    // 即使没有发起请求,也返回完整的合并数据
    select: (data) => {
      if (!data) return cachedItems;
      return [...cachedItems, ...data];
    },
  });
};

方案优势

  • 完全避免对已缓存ID的重复请求,极大减少网络开销
  • 组件能立即拿到已缓存的数据渲染,请求完成后自动补充新数据,体验更流畅

注意事项

  • 务必对ID数组排序后作为查询键的一部分,避免因ID顺序不同导致重复缓存
  • 如果后端返回的数组顺序和请求ID顺序不一致,需要在select或onSuccess中按原ID顺序重新整理数据,保证返回结果的顺序正确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:35:18