如何在React Query中合并两个useQuery请求返回单组数据?
合并多个useQuery请求的优化方案
你在表单组件中通过两个独立的useQuery Hook从不同接口获取数据填充表单,希望能合并这两个查询,返回单个对象/数组供组件使用,以下是几种可行的优化方案:
方案1:使用useQueries批量处理查询
react-query(@tanstack/react-query)提供了useQueries钩子,专门用于并行处理多个查询请求,它会返回一个包含所有查询结果的数组,你可以基于这个数组合并数据并统一处理状态:
import { useQueries } from '@tanstack/react-query'; // 封装批量查询的自定义Hook export const useFetchCompanyData = (integrationId, companyId) => { const queries = useQueries({ queries: [ { queryKey: [companies.fetchCompanyIntegration, integrationId], queryFn: async () => { const { data } = await axios({ url: '你的集成接口地址', // 替换为实际URL method: 'get', responseType: 'json' }); return data; } }, { queryKey: [companies.fetchCompanyByID, companyId], queryFn: async () => { const { data } = await axios({ url: '你的公司详情接口地址', // 替换为实际URL method: 'get', responseType: 'json' }); return data; } } ] }); // 合并数据:当两个请求都完成时,返回合并后的对象 const combinedData = queries.every(q => q.data) ? { companyIntegration: queries[0].data, company: queries[1].data } : undefined; // 统一加载状态:只要有一个请求在加载,就返回true const isLoading = queries.some(q => q.isLoading); // 统一错误状态:只要有一个请求出错,就返回对应的错误 const error = queries.find(q => q.error)?.error; return { data: combinedData, isLoading, error }; };
组件中调用这个Hook:
const { data: companyData, isLoading, error } = useFetchCompanyData(integrationProp.id, currentCompany.id); // 使用数据:当data存在时,可直接解构使用 if (companyData) { const { companyIntegration, company } = companyData; // 填充表单逻辑 }
方案2:自定义Hook中并行发起请求
如果你不想依赖useQueries,也可以在自定义Hook中通过Promise.all并行发起两个请求,结合单个useQuery来处理:
export const useFetchCompanyData = (integrationId, companyId) => { return useQuery( ['companyCombinedData', integrationId, companyId], // 组合唯一的queryKey async () => { // 并行发起两个请求 const [integrationRes, companyRes] = await Promise.all([ axios({ url: '你的集成接口地址', method: 'get', responseType: 'json' }), axios({ url: '你的公司详情接口地址', method: 'get', responseType: 'json' }) ]); // 返回合并后的对象 return { companyIntegration: integrationRes.data, company: companyRes.data }; } ); };
组件中调用:
const { data: companyData, isLoading, error } = useFetchCompanyData(integrationProp.id, currentCompany.id); // 直接使用合并后的数据 if (companyData) { // 用companyData.companyIntegration和companyData.company填充表单 }
两种方案对比
- useQueries方案:保留了每个查询独立的缓存、重试等配置,适合需要对不同请求设置不同参数(比如不同的retry次数、缓存时间)的场景,灵活性更高。
- Promise.all+单个useQuery方案:将两个请求视为一个整体查询,缓存和配置统一,适合两个请求强关联、需要同时成功/失败的场景,代码更简洁。
内容的提问来源于stack exchange,提问作者boogiehsows
相关产品推荐
相关产品推荐

