You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:45:31