TanStackT
TanStack9mo ago
2 replies
dead-brown

setDefaultOptions -> refetchQueries race condition?

I'm trying to set a global
meta
option that my queryFns will recognize and do a fetch(..., {cache: "reload"}) HTTP request.

I came up with this:

  const reloadQueries = async () => {
    queryClient.setDefaultOptions(produce(queryClient.getDefaultOptions(), (draft) => {
      set(draft, ["queries", "meta", "reload"], true)
    }));

    // this will actually call my queryFn with the old `meta = {}`
    await queryClient.refetchQueries({type: "active"})

    // this one will make the queryFn finally pass meta.reload == true
    await queryClient.refetchQueries({type: "active"})
    // TODO: uncomment once I figure out the race condition
    // queryClient.setDefaultOptions(produce(queryClient.getDefaultOptions(), (draft) => {
    //   set(draft, ["queries", "meta", "reload"], false)
    // }));
  };

// ...
<button onClick={reloadQueries}>Reload queries</button>


My queryFn looks like this:

async function queryFn({signal, meta = {}, client}: {signal: AbortSignal, meta?: Record<string, unknown>, client: QueryClient}) {
  console.log("in queryFn", JSON.stringify(meta))
  console.log("in queryFn still", JSON.stringify(client.getDefaultOptions().queries))
  const response = await fetch(
    `${API_URL}/some-enpoint`,
    {cache: meta.reload ? "reload" : 'default', /* signal */}
  );
  // ...
}


So the result is that after the first refetchQueries, my queryFn gets called with meta === {} but the default options are observable and up to date already, with meta.reload == true. Only by the second refetchQueries are both
meta
and client.getDefaultOptions().queries.meta the same within
queryFn
.

I also tried it with invalidateQueries (which I looked at the code that it eventually calls refetchQueries and is also awaitable), but the behavior is the same.

Am I missing something? I did not expect it to be delayed like this. I could always use client.getDefaultOptions() in my queryFns but I'd rather figure out the root cause.
Was this page helpful?