reactjstypescriptreact-querytanstackreact-query

getQueryData always returns undefined even when set with useMutation - TanStack Query, React


When I try to read cache content of given key I receive undefined even after I call useMutation with exactly same key.

Mutation used to set cache (mutation returns proper data, as expected):

const axiosInstance = axios.create(habiticaAPIconf);

function parseResponse(response:LoginDataContract):AuthData{
  return {
    id: response.data.id,
    apiToken: response.data.apiToken,
    username: response.data.username
  }
}

const getAuthenticationData = async (userCredentials:UserCredentials):Promise<AuthData> => {
  const response = await axiosInstance.post<LoginDataContract>("/user/auth/local/login", {...userCredentials});
  return parseResponse(response.data);
}

export function useCredentialData() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
    mutationKey: ['authData']
  });
};

Component used to fire the mutation:

export function LoginForm() {
  const { mutate, isSuccess, data } = useCredentialData();

  function handleLogin(e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) {
    e.preventDefault();
    mutate({
      username: (document.getElementById("email") as HTMLInputElement).value,
      password: (document.getElementById("password") as HTMLInputElement).value
    });
    console.log(data);
  }

  return (
    <form>
      <label htmlFor="email">
        <input type="email" name="email" id="email"></input>
      </label>
      <label htmlFor="password">
        <input type="password" name="password" id="password"></input>
      </label>
      <button type="submit" onClick={ (e)=> {handleLogin(e)}}>Login</button>
      <span>{isSuccess ? `${data.username}` : ""}</span>
    </form>
  )
}

While clicking button in React Component undefined is always received even after abovementioned mutatuion is called and returns proper data.

import { useQueryClient } from "@tanstack/react-query";

export function SidebarTasksList() {
  const queryClient = useQueryClient();

  return (
    <section>
      <button onClick={
        ()=>console.log(queryClient.getQueryData(['authData']))
      }>CLICK</button>
    </section>
  );

How to retrive data stored in ['AuthData'] cache? There is no function I could pass to useQuery as queryFn either, that's why I'm tring with getQueryData.


Solution

  • Generally speaking, mutations and queries have no correlation. Setting the same key on both of them does not achieve that they know about each other. The mutationKey is also optional. None of the examples actually set the key if I remember correctly because it's mostly used to share configuration between mutations.

    What you need to do to "link" the result of your mutations to your queries is to either:

      return useMutation({
        mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
        onSuccess: () => queryClient.invalidateQueries(['authData'])
      });
    
      return useMutation({
        mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
        onSuccess: (data) => queryClient.setQueryData(['authData'], data)
      });