Search code examples
reactjsreact-querytanstack

react-query useQuery not refetching after useMutation


I am using react-query (actually tanstack/react-query v4) to query from and mutate a db. Based on docs and research, I gather that useQuery will automatically refetch from the server if/when the server-state differs from the cached state.

However, after I useMutation to update my db, the impacted query does not immediately refetch.

I know that the useMutation is working based on viewing the db on server-side, but also because I can manually refetch using react-query dev tools, and get the new values just fine.

On reading, I have tried two approaches:

  const addMover = useMutation({
    mutationFn: (newMover) => { ... },
    onSuccess: () => {
      queryClient.invalidateQueries(["movers"]);
      console.log("The mutation is sucessful!");
    },
  });

---> When this mutation gets run, I do see the 'onSuccess' console.log() coming through, but the query still shows as 'stale' in the dev-tools and does not get re-rendered.

  • I also tried (in a different place) the "SetQueryData" pattern from the useMutation response, as outlined in the docs...
const handleDelete = useMutation(
    {
      mutationFn: (wktID) => { ... },
      onSuccess: (data) => {
        queryClient.setQueryData(["workouts", [activeMover]], data);
      },
    }
  );

My expectation from either approach is simply that the mutated db gets re-queried and re-rendered. I'd prefer to SetQueryData and save a network request, but either approach would make me happy :).


Solution

  • I was able to solve this! The issue here was that I was not explicitly returning anything from the mutationFnc in my useMutation definition.

    This meant that onSuccess was getting triggered by the return of an 'OPTIONS' request, and not the actual 'POST', and since at that point the DB had not been updated, there was nothing new to fetch w/ useQuery.

    By adding a 'return' to the function, it now waits for the Promise before triggering onSuccess, and my mutation now gets rendered by the useQuery. Like this...

    const addMover = useMutation({
        mutationFn: (newMover) => { ... },
        onSuccess: () => {
          return queryClient.invalidateQueries(["movers"]);
          console.log("The mutation is sucessful!");
        },
      });
    

    So be sure to treat your mutationFnc as a proper async function, that waits for the Promise to get resolved! (Duh :).