如何基于返回三级嵌套数据的useQuery结果使用useQueries?
解决嵌套URL数组下的TanStack Query依赖查询问题
问题分析
你遇到的核心问题是:第一个useQuery返回嵌套结构的URL数组,需要提取所有URL并用useQueries批量获取数据,但之前的实现因条件性调用Hook触发了Rendered more hooks than during the previous render错误——这是因为React要求组件每次渲染时,Hook的调用顺序和数量必须完全一致,不能在if等条件语句内调用Hook。
解决方案
不需要修改第一个useQuery的返回格式,只需在组件顶层稳定调用useQueries,同时正确提取嵌套结构中的所有URL即可:
// 获取嵌套结构的原始数据 const { data: userGroups, isLoading, isError } = useQuery({ queryKey: ['users'], queryFn: getUsersData }); // 提取所有嵌套的URL:将二级结构中的id数组扁平化 const allUrls = userGroups?.flatMap(group => group.id) || []; // 稳定调用useQueries,无论数据是否加载完成 const allUrlData = useQueries({ queries: allUrls.map(url => ({ queryKey: ['url-data', url], queryFn: () => fetchUrlData(url), // 替换为你的实际请求函数 // 可选:仅当URL有效时才触发请求,避免无效调用 enabled: !!url })) });
关键细节说明
- 禁止条件性Hook调用:
useQueries必须在组件顶层调用,不能放在if (!isLoading)这类条件块中。即使allUrls是空数组,useQueries也只会返回空数组,不会引发Hook调用数量变化的问题。 - 扁平化嵌套数组:使用
flatMap可以高效提取所有嵌套的URL,替代手动循环拼接数组的方式,代码更简洁。 - 可选的enabled控制:给每个子查询添加
enabled: !!url,可以避免对空值URL发起无效请求,优化性能。
错误原因复盘
你之前的实现中,可能将useQueries放在了if (!isLoading)的条件判断内,导致组件首次渲染时(isLoading=true)不调用该Hook,数据加载完成后(isLoading=false)才调用,违反了React Hook的调用规则,因此抛出错误。
内容的提问来源于stack exchange,提问作者SamTest
相关产品推荐
相关产品推荐

