React Query useQuery报"No overload matches this call"错误排查
React Query useQuery中onSuccess报错"No overload matches this call"的原因分析
错误信息
No overload matches this call. Overload 1 of 3, '(options: UndefinedInitialDataOptions<any, Error, any, string[]>, queryClient?: QueryClient | undefined): UseQueryResult<any, Error>', gave the following error. Argument of type '{ queryKey: string[]; queryFn: () => Promise<any>; retry: false; onSuccess: (res: { data: React.SetStateAction<IUser | null>;}) => void; onError: () => void; }' is not assignable to parameter of type 'UndefinedInitialDataOptions<any, Error, any, string[]>'. Object literal may only specify known properties, and 'onSuccess' does not exist in type 'UndefinedInitialDataOptions<any, Error, any, string[]>'. Overload 2 of 3, '(options: DefinedInitialDataOptions<any, Error, any, string[]>, queryClient?: QueryClient | undefined): DefinedUseQueryResult<any, Error>', gave the following error. Argument of type '{ queryKey: string[]; queryFn: () => Promise<any>; retry: false; onSuccess: (res: { data: React.SetStateAction<IUser | null>;}) => void; onError: () => void; }' is not assignable to parameter of type 'DefinedInitialDataOptions<any, Error, any, string[]>'. Object literal may only specify known properties, and 'onSuccess' does not exist in type 'DefinedInitialDataOptions<any, Error, any, string[]>'. Overload 3 of 3, '(options: UseQueryOptions<any, Error, any, string[]>, queryClient?: QueryClient | undefined): UseQueryResult<any, Error>', gave the following error. Argument of type '{ queryKey: string[]; queryFn: () => Promise<any>; retry: false; onSuccess: (res: { data: React.SetStateAction<IUser | null>;}) => void; onError: () => void; }' is not assignable to parameter of type 'UseQueryOptions<any, Error, any, string[]>'. Object literal may only specify known properties, and 'onSuccess' does not exist in type 'UseQueryOptions<any, Error, any, string[]>'. 38 | queryFn: getUserInfo, 39 | retry: false, > 40 | onSuccess: (res: any) => { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ > 41 | setUser(res.data); | ^^^^^^^^^^^^^^^^^^^^^^ > 42 | setAuthenticated(true); | ^^^^^^^^^^^^^^^^^^^^^^ > 43 | },
相关代码
UserProvider组件代码
import React, { createContext, Dispatch, ReactNode, SetStateAction, useState } from 'react'; import { IUser } from '../interfaces/user'; import { useQuery } from '@tanstack/react-query'; import { getAccessToken, getUserInfo, removeAccessToken } from '../services/auth'; import { useNavigate } from 'react-router-dom'; type UserContextType = { user: IUser | null; isAuthenticated: boolean; isCurrentUserLoad: boolean; setUser: Dispatch<SetStateAction<IUser | null>>; setAuthenticated: Dispatch<SetStateAction<boolean>>; logout: () => void; }; type UserContextProviderProps = { children: ReactNode; }; export const UserContext = createContext({ user: null, isAuthenticated: false, isCurrentUserLoad: false, logout: () => {}, } as UserContextType); export const UserProvider = ({ children }: UserContextProviderProps) => { const [user, setUser] = useState<IUser | null>(null); const [isAuthenticated, setAuthenticated] = useState(false); const [isCurrentUserLoad, setIsCurrentUserLoad] = useState(false); const navigate = useNavigate(); const { isLoading, refetch: getCurrentUser } = useQuery({ queryKey: ['user'], queryFn: getUserInfo, retry: false, onSuccess: (res: any) => { setUser(res.data); setAuthenticated(true); }, onError: () => { setUser(null); setAuthenticated(false); removeAccessToken(); }, }); const logout = () => { setUser(null); setAuthenticated(false); removeAccessToken(); navigate('/'); }; return ( <UserContext.Provider value={{ user, isAuthenticated, logout, isCurrentUserLoad, setUser, setAuthenticated, }} > {children} </UserContext.Provider> ); };
getUserInfo函数代码
export const getUserInfo = async () => { try { const accessToken = localStorage.getItem('access_token'); if (!accessToken){ throw new Error('Access token not found'); } const response = await axiosClient.get('/users/userinfo', { headers: { Authorization: `Bearer ${accessToken}`, }, }); return response.data; } catch (error) { console.error("API error:", error); throw error; } };
问题原因
你使用的是React Query v4版本,该版本已移除useQuery配置项中的onSuccess、onError、onSettled这类回调属性——这些回调在React Query v3中是合法配置,但v4为了简化API设计,将它们从useQuery的直接配置中移除,因此TypeScript会提示这些属性不属于UndefinedInitialDataOptions、DefinedInitialDataOptions或UseQueryOptions类型。
解决方法
可以通过useEffect监听useQuery返回的状态来替代原回调逻辑:
// 在UserProvider组件中添加以下useEffect import { useEffect } from 'react'; // ...其他代码 const { isLoading, data, isError, refetch: getCurrentUser } = useQuery({ queryKey: ['user'], queryFn: getUserInfo, retry: false, }); useEffect(() => { // 替代原onSuccess逻辑 if (data) { setUser(data); // 注意getUserInfo已直接返回response.data,无需再取res.data setAuthenticated(true); } }, [data]); useEffect(() => { // 替代原onError逻辑 if (isError) { setUser(null); setAuthenticated(false); removeAccessToken(); } }, [isError]);
内容的提问来源于stack exchange,提问作者mikasa akerman
相关产品推荐
相关产品推荐

