Search code examples
react-contextreact-query

why the error "No overload matches this call" occurs?


I am working with react query's useQuery function, and I want to set the user and the authenticated variable in the onSuccess function, but this error occurs:

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 |   },

And here is my the code:

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(!!getAccessToken());
  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,
      }}
    >
      {/* {isCurrentUserLoad ? <Loading /> : children} */}
      {children}
    </UserContext.Provider>
  );
};


And here is the getUserInfo function:

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;
  }
};


So what's the problem please?


Solution

  • What version of @tanstack/react-query are you using?

    onSuccess was valid in v4 but is not in v5.

    https://tanstack.com/query/v5/docs/framework/react/reference/useQuery