使用RTK Query创建自定义查询时遇Promise类型错误,求排查
自定义查询签名获取引发的类型错误分析
需求背景
需先通过POST请求获取签名,再将该签名用于另一个GET请求,以此创建自定义查询。
实现代码
export const useSignatureCustomQuery = (arg: string) => { const [getSignature] = useGetSignatureKeyMutation(); const signature = getSignature({ url: `${REST_END_POINTS.GET_SIGNATURE}`, }) .unwrap() .then((res) => res.data.attributes.signature); const data = useFetchDataQuery(arg, { skip: !signature , }); return { data }; };
使用方式
const { data: query } = useSignatureCustomQuery( REST_END_POINTS.POSITION_INFORMATION, !!positions );
错误信息
Property 'data' does not exist on type 'Promise<{ data: UseQueryHookResult<QueryDefinition<string, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {} & RetryOptions, FetchBaseQueryMeta>,
问题根源
- 异步操作处理错误:
getSignature()是异步Mutation,调用后返回的是Promise对象,所以signature变量的类型是Promise<string>,而非预期的签名字符串。直接用!signature作为skip条件时,Promise永远是真值,导致useFetchDataQuery不会被跳过,同时类型系统检测到类型不匹配,抛出错误。 - Hook使用违规:在React Hook的顶层直接调用异步操作并赋值,会导致组件每次渲染都重复触发POST请求,既浪费资源也不符合Hook的使用规则。
- 参数不匹配:自定义查询定义只接收一个
arg参数,但调用时传入了第二个参数!!positions,导致参数个数不匹配,进一步加剧类型错误。
修复方案
1. 正确处理异步签名获取,用状态存储结果
修改自定义查询,通过useState保存签名值,useEffect触发异步请求:
import { useState, useEffect } from 'react'; export const useSignatureCustomQuery = (arg: string, additionalSkip: boolean = false) => { const [getSignature] = useGetSignatureKeyMutation(); const [signature, setSignature] = useState<string | undefined>(undefined); useEffect(() => { const fetchSignature = async () => { try { const res = await getSignature({ url: `${REST_END_POINTS.GET_SIGNATURE}`, }).unwrap(); setSignature(res.data.attributes.signature); } catch (error) { console.error('签名获取失败:', error); // 可根据需求添加失败后的处理逻辑,比如设置默认值或抛出错误 } }; fetchSignature(); }, [getSignature]); const data = useFetchDataQuery(arg, { skip: !signature || additionalSkip, }); return { data }; };
2. 匹配调用参数
修改后的自定义查询支持第二个可选的additionalSkip参数,调用方式保持不变即可:
const { data: query } = useSignatureCustomQuery( REST_END_POINTS.POSITION_INFORMATION, !!positions );
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

