How to stop multiple calls of the same query using React-query?

Viewed 297

I am using React-query for my React app.

I have useLogin and useLogout hooks which use useQuery:

export const useLogin = (input?: LoginWithEmailPassword) => {
  const { data, isLoading, isSuccess, error } = useQuery(
    ["loginWithEmailPassword"],
    () => loginWithEmailPassword(input),
    {
      enabled: !!input,
    }
  );

  return { data: data?.data, isLoading, isSuccess, error };
};

export const useLogout = (accessToken?: string) => {
  const { isSuccess, isLoading, error } = useQuery(
    ["logout"],
    () => logout(accessToken),
    {
      enabled: !!accessToken,
    }
  );

  return { isSuccess, isLoading, error };
};

In my AuthProvider; where I use the 2 hooks, I also have a login and logout function which will be called when a user clicks login/logout.

Given React-query's declarative approach, I'm also keeping 2 states; loginInput and logoutInput

AuthProvider.tsx

  const [loginInput, setLoginInput] = useState<LoginWithEmailPassword>();
  const [logoutInput, setLogoutInput] = useState<string | undefined>();

  const { data, isSuccess: isLoginSuccess, isLoading } = useLogin(loginInput);
  const {...} = useLogout(logoutInput);

  const login = (input: LoginWithEmailPassword) => {
    setLoginInput(input);
  };

  const logout = () => {
    setLogoutInput(data?.accessToken);
  };

This issue I've found is that after the user clicks login and set's the loginInput state; useLogin will run. But useLogin will re-run every time the component re-rerenders because loginInput will still have the state; i.e. if a user clicks logout, useLogin will run again. What would be the best way to resolve this?

Things will be more straightforward if React-query has a useLazyQuery like Apollo.

A hacky approach I can think of is to reset the loginInput state to undefined, like so:

useEffect(()=>{
if(isLoginSuccess && !isLoading && !!data) setLoginInput(undefined)
},[isLoginSuccess])
1 Answers

login and logout are not queries, but mutations. They are not idempotent - you can't run them at will. They change some state on the server (logging the user in) or create a resource (a login token).

So, the answer is: don't use queries here.

Related