Search code examples
reactjsreact-querytanstackreact-query

data argument in onSuccess handler in useMutation function in react query is not defined, and the handler is being fired before request is finished,


i'm using useMutation in react query and passing the mutationFn and also passing options to run code on success and on error this is the code from useMutation

  const {
    mutate: login,
    isSuccess,
    isPending,
  } = useMutation({
    mutationKey: "login",
    mutationFn: ({ identifier, password }) => {
      loginApi({ identifier, password });
    },
    onSuccess: (data) => {
      console.log(data);
    },
    onError: (err) => {
      console.log(err);
    },
  });

then i'm using the mutate function in a form submit handler and passing variables object to it and an onSettled object to clear input fields from useState... this is the how i'm using the mutate function which i renamed to login

  const handleLoginSubmit = (e) => {
    e.preventDefault();

    login(
      { identifier, password },
      {
        onSettled: () => {
          setIdentifier("");
          setPassword("");
        },
      }
    );
  };

and this is the mutationFn which is an async function that request certain backend route with the variables and return the response data

export async function login({ identifier, password }) {
  const res = await fetch(`${API_URL}/users/login`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emailOrUsername: identifier, password }),
  });

  const data = await res.json();

  if (data.status !== "success") {
    throw new Error(data.data.data);
  }

  return data;
}

but the problem is that onSuccess data argument is undefined and onSuccess is fired immediately after submission without waiting for the request to finish... and i dont know why.. i checked the code multiple times but didnt find any error... anyone can help me?

i tried to run a function after successfully finishi icon. ng a request with useMutation on react query... i used onSuccess option...

i expected that this function will run after the request finishes and that it will get data as a 1st argument... what actually resulted is that onSuccess handler runs before the request finishes and the data argument is undefined.


Solution

  • mutationFn: ({ identifier, password }) => {
        loginApi({ identifier, password });
    },
    

    If this is your exact code than the mutationFn doesn't return anything, therefor it returns undefined. You miss the return statement, compare with:

    mutationFn: ({ identifier, password }) => {
        return loginApi({ identifier, password });
    },
    

    It also explains why onSuccess runs "immediately" - as the mutation function doesn't return a promise, it doesn't wait for that promise to resolve.