2

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 :).

welew204
  • 41
  • 7
  • Where is the `["movers"]` query used? – Slava Knyazev Feb 10 '23 at 19:20
  • `["movers"]` is used to populate a sidebar nav, and then activeMover (selected) is saved in app-wide state and re-useQuery'd on many different components. I am assuming here that react-query is accessing from state when/where possible, rather than refetching at each instance, in each component. Does that answer your question @SlavaKnyazev ? – welew204 Feb 11 '23 at 20:44
  • Could you please provide more code about the `useQuery(["movers"])` and `useQuery(["workouts", [activeMover]])`? Cause I'm thinking that maybe you triggered not the same query keys. – haptn Feb 13 '23 at 10:20
  • @haptn Thanks for the question--using the tanstack-query dev tools, I can see what queries are held in cache, and their query keys are listed, and in both cases showed above I have matched those query keys exactly. Is that what you mean? If not, I can share the initial useQuery call.... ? – welew204 Feb 15 '23 at 14:52
  • @tkdodo any chance you could chime in here?? – welew204 Feb 15 '23 at 14:52
  • impossible to say without seeing a full example. likely, the queryKeys are not matching up. you should see that in the react-query-devtools. Or, your query client is not stable: https://tkdodo.eu/blog/react-query-fa-qs#why-are-updates-not-shown – TkDodo Feb 26 '23 at 09:01

2 Answers2

2

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 :).

welew204
  • 41
  • 7
  • Welcome to Stack Overflow! Make sure to always include code on your answer! [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) – William Brochensque junior Mar 03 '23 at 18:16
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 03 '23 at 18:17
-3

If you want to re-fetch data after mutation you edit your mutation and leave it like this:

const [createHabit, { error, loading }] = useMutation(CREATE_HABIT_MUTATION, {
    refetchQueries: [{ query: HABITS_QUERY }],
  });

Here you can find an example.

jcobo1
  • 1,065
  • 1
  • 18
  • 34
  • 1
    If you're going to provide a link for reference it's a better idea to link to the official docs rather than a random blog. Also, the example in the article is not based on react-query which is the library OP is using. – ivanatias Feb 10 '23 at 21:19
  • Thanks @jcobo1 for the reply, but I'm not using Apollo or GraphQL for this project, just SQLite and flask. – welew204 Feb 12 '23 at 15:13