TanStackT
TanStack2w ago
1 reply
brilliant-lime

invalidateQueries vs cancelQueries + refetchQueries for in-flight race conditions

I have an edge case I'm trying to work through on an app that combines server-side events + traditional fetching.

It's basically a chat application that receives new_message events that update both the inbox and conversation window.

The race condition is this:
1) User clicks a chat - this triggers a fetch for the conversation from the DB
2) While that query is fetching, a new_message event comes in for that in-flight conversation
3) Original query (#1) completes, message from #2 does not appear in the chat
4) User has to wait ~20 seconds (backup polling mechanism) to see the message from #2

I have code that looks like this:

const newMessage = eventData.data as Message;
      const queryKey = queryKeys.conversations.detail(userId);
      const existingData =
        queryClient.getQueryData<FetchConversationHistoryByTicketResponse>(
          queryKey
        );

      if (!existingData) {
        // We're on this conversation's route but no cache — fetch must be in-flight
        // Invalidate so when current fetch completes, a refetch is triggered
        queryClient.invalidateQueries({ queryKey });
        return;
      }


I'm just wondering if invalidateQueries is the correct API here or if cancelQueries + refetchQueries is more appropriate? My instinct is that invalidate would mark the query as stale which would immediately cause another refetch, but I was not 100% positive on the expected behavior of the API or how staleness propagates.

Been trying to write some tests but this is pretty flaky and tricky logic to get exactly right in a test.
Was this page helpful?