Skip to content

Redundant queries invalidation when combining useQuery with fetchQuery in v5 #7129

Closed as not planned
@izri16

Description

@izri16

Describe the bug

Consider the below code that uses fetchQuery inside useQuery. Note that this is meant to be a minimalistic example, you can also find a link for playground here https://codesandbox.io/p/sandbox/pedantic-kapitsa-jvv78v?file=%2Fsrc%2FApp.js:

import {useQuery} from '@tanstack/react-query'

const fn2 = async () => {
  const result = Math.random()
  console.log('FN_2', result)
  return result
}

const fn1 = async () => {
  const result = Math.random()
  console.log('FN_1', result)

  await queryClient.fetchQuery({
    queryKey: ['fn_2'],
    queryFn: fn2,
    staleTime: Infinity,
  })

  return result
}

export function main() {
  useQuery({
    queryKey: ['fn_1'],
    queryFn: fn1,
    staleTime: Infinity,
  })

  useQuery({
    queryKey: ['fn_2'],
    queryFn: fn2,
    staleTime: Infinity,
  })

  const refetch = async () => {
    await queryClient.invalidateQueries()
  }

  return // some UI when `refetch` can be called, e.g. on click
}

Now the problem is that when refetch is called and invalidation happens the following is being logged:

FN_1
FN_2
FN_2
FN_1

Though, given the example uses staleTime: Infinity and the react-query is meant to guarantee that duplicate requests are not fired I would expect to see this sequence instead:

FN_1
FN_2

or

FN_1
FN_2
FN_2

Even if react-query runs separate fetch for fn2, one for fetchQuery, and one for useQuery, this does not explain why fn1 is being called two times.

We noticed this behavior once updating from v3. Though it seems to go away when using cancelRefetch: false it still seems incorrect even with cancelRefetch: true. The motivation for using fetchQuery inside useQuery callback is that we often use it to reuse other query functions from imperative code and also cache their values at the same time, while avoiding duplicate requests.

Could you please confirm whether is this behavior expected and if yes point to some docs or explain why, or confirm that its a bug?

Thanks a lot.

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/pedantic-kapitsa-jvv78v?file=%2Fsrc%2FApp.js

Steps to reproduce

  1. Open link to sandbox
  2. Open sandbox console
  3. Clear sandbox console
  4. Click on "Invalidate queries" button
  5. You should see 4 console logs like this:
FN_1 0.49671699048416773
FN_2 0.34992822118130174
FN_2 0.3922700001128352
FN_1 0.16330643108671228

Expected behavior

I would expect to only see FN_1, FN_2 logs in the console or FN_1, FN_2, FN_2.

How often does this bug happen?

Every time

Screenshots or Videos

[

Screen.Recording.2024-03-17.at.11.33.42.mov

](url)

Platform

OS - [macOS]
browser - Chrome
version - 122.0.6261.112

Tanstack Query adapter

None

TanStack Query version

5.27.3

TypeScript version

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions