React Query解构useQueries返回值报data不存在于void类型错误
报错原因
报错由两个问题共同导致:
- 直接原因:
useQuery返回的defaultSettingTypes初始值为undefined。React Query在请求未完成、未手动设置初始值时,data字段默认值是undefined,首次渲染时执行defaultSettingTypes.map()会直接触发运行时错误,导致Hook函数执行中断,无法走到return userQueries的逻辑,最终TS推断Hook返回类型为void,自然不存在data属性。 - 根本逻辑问题:对
useQueries的返回结构认知错误。useQueries用于并发发起多个查询,返回值是每个查询结果组成的数组,数组中的单个元素才是和useQuery返回结构一致的对象(包含data/isLoading/error等字段),本身不存在顶层的data属性,就算解决了map执行报错的问题,直接解构顶层data的写法也不符合API设计。
修复方案
- 首先给
defaultSettingTypes加空值兜底,避免首次渲染执行map时报错中断Hook执行,推荐使用React Query v3+ 标准的useQueries对象传参格式,获得更准确的TS类型推导:
const useGetAllChannelSettingTypes = () => { const {data: defaultSettingTypes} = useQuery(SETTING_TYPES, () => Api.user.getSettingTypes(), ); // 给defaultSettingTypes加空值合并兜底,初始为空数组时useQueries会正常返回空数组 const userQueries = useQueries({ queries: (defaultSettingTypes ?? []).map((type) => ({ queryKey: ['SETTING_VALUE', type.channelSettingTypeId], queryFn: () => Api.user.getSettingValues(type.channelSettingTypeId), })), }); // 按需聚合返回结果,方便调用侧使用 return { defaultSettingTypes, allSettingValues: userQueries.map(res => res.data), isLoading: userQueries.some(res => res.isLoading), isError: userQueries.some(res => res.isError), } };
- 调整Hook调用侧的解构逻辑,匹配你定义的返回结构即可:
const {allSettingValues: getAllChannelSettingTypes, isLoading} = useGetAllChannelSettingTypes();
如果你不想修改Hook的返回结构,保持原有返回userQueries数组的逻辑,那么调用时不能解构顶层data,需要遍历返回的结果数组获取每个查询的对应数据:
const queryResults = useGetAllChannelSettingTypes(); // 遍历数组取每个查询的data const allSettingTypes = queryResults.map(item => item.data);
内容的提问来源于stack exchange,提问作者Fathe
相关产品推荐
相关产品推荐

