query: useQuery randomly not returning data and stuck in loading

Describe the bug After upgrading to react-query 3.5.11 from 2.26.4 last week, our project’s Cypress tests started failing randomly because the app started showing a loading spinner at random times. After a lot of head-banging, we finally tracked down the issue: even though, based on the network inspector, the request had gone through successfully, react-query’s useQuery was returning an object with isLoading as true and data as undefined. Reverting back to react-query 2 fixed the problems.

Most of the requests in our Cypress tests are stubbed using cy.server and cy.route. This probably shouldn’t affect react-query but mentioning it here just in case.

Our cache is configured in the following manner at the top of one of our source files, so this shouldn’t be caused by us accidentally creating multiple caches:

const queryCache = new QueryCache({
  defaultConfig: {
    queries: {
      staleTime: 10 * 60 * 1000,
      cacheTime: 15 * 60 * 1000,
      retry: (
        _failureCount,
        error: any,
      ) => error.status !== 403 && error.status !== 401,
    },
  },
});

// Further down:

class AppProvider extends Component<{}, State> {
  public render() {
    return (
      <ReactQueryCacheProvider queryCache={queryCache}>
        {/* ... */}
      </ReactQueryCacheProvider>
    );
  }
}

To Reproduce Unfortunately, this happens randomly and is thus very hard to reproduce. The randomness does point towards some type of race condition. Our app performs many (~10) requests on startup.

Even though which tests fail is random, I can consistently get at least one test to fail. Is there something I can do to help track down what could be the issue?

Expected behavior useQuery should return the data it receives in the response once the request is successful.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Chrome
  • Version: 87

Additional context Happens on both Cypress version 5.3.0 and 6.2.1.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 12
  • Comments: 85 (1 by maintainers)

Most upvoted comments

@fermmm It sounds like your issue may be different than what I’m experiencing. My issue is that even though data was successfully received by the app, useQuery thinks that it’s still loading the data and never provides it to the app.

So this probably means something wrong is happening in the code

no, this is an issue with navigator.onLine in chrome on macos, which we are using in v4 to determine if you are online or not.

Since navigator.onLine is broken, we’ve moved away from using it in v5

I am going to add a +1 to this. I am facing this exact issue where isLoading gets stuck in true and data comes back as undefined. I am using the same query in two components the first component fires the query and gets the data fine, but on the second component the same query (with the same key) gets stuck and returns undefined. This is a bizarre situation that I am not sure I am able to wrap my head around.

Here’s whats happening

Component - 1
    Query 1 --> Works 
    Query 2 --> Works

Component - 2
   Query 1 --> Works with same key as in component 1
   Query 2 --> Doesn't Work with same or different key

Component 1 and 2 are quite similar in how they work, Query-1 and Query-2 uses the same async functions (with different service endpoints). I will say that at some point I had this QueryClient setup (I am not sure why I setup this way)

const queryClient = new QueryClient({defaultOptions: {
  queries: {
    retryDelay: 1,
    retry:0,
  }
}});

Changing this to the following didn’t work either

const queryClient = new QueryClient();

Hi I have a similar issue on the version 4. I see there is a tag port-to-v4 in the #1737 fix, but was this fix really ported to v4? I’m not familiar with the organisation of the repo. There are 4 branches: 1.x, 2.x, v3, v5 and none for v4.

@TkDodo, I’m sorry for disturbing you, but could you check if this fix is present in v4, please? <video src="https://user-images.githubusercontent.com/1058402/216065119-f4071fae-27d9-4189-9c1b-f82cc827bc97.mov"></video> I’ve spent many hours trying to track the root cause o the issue, because it happens only on CI (like 1/5 times) on my project and then found this issue for v3.

In my case this only happens when I restart my RN app when all the components are loading for the first time

I also have the same issue in my react native application, it is a random issue, sometimes isLoading and isFetching get stuck and data stays undefined even if the network request is done successfully. When I restart the app it works fine! Hopefully they can fix this issue as soon as possible

edge and brave are both built on chromium … they are the same thing and have the same behaviour / bugs in this regard

I’m also facing the same issue since recently on v4.

invalidating a query (as result of a mutation, or manually via dev tools) will make it transition to ‘isFetching’, but won’t transition again to ‘success’. DevTools show it stuck in fetching. Components using the query will render only once and see it in ‘success’ status with old data, never receiving the updated data.

Unfortunately no minimal repro from me either, but I have noticed that this happened once I moved some of the query dependencies out of a context and inside a state manager (Jotai). In theory this does not imply any change in the query rendering, but the timing is very suspicious in my case

@MatkoMilic again, this is not very helpful I’m afraid. Without an isolated reproduction, there is only so much I can do 🤷

Hello, I’m running 4 API calls in the same component with different keys using “useQuery” and I used QueriesObserver to see what is happening in the background. Basically, in the observer, the data is up to date and the isLoading state has changed to false, but this does not reflect on the variables which are extracted from useQuery. is there a way to force a useQuery to check the observer again?

@TkDodo Btw this is on a react native project

It’s quite strange.

again, I’m positive that this is related to navigator.onLine being broken in chrome, which is not our fault. What is our fault is that we were relying on it to work properly in the first place, which is what we’ve changed in v5.

you can validate that assumption by looking at the fetchStatus returned from useQuery when that happens. If the fetchStatus is 'paused', you’ll know that this is indeed the case.

again, you can:

  • update to v5, which has a different default behaviour
  • set networkMode: 'offlineFirst' to work around it
  • get the bugs fixed in chrome 🤷

See am encountering the same issue with v4.36, It tends to make requests successfully to jsonplaceholder however when I make a request to my local server it then stucks on the loading, When I use the use Effect hook and state everything works well, I’ve seen this stuck issue has been perturbing from v2 all the way to v4, why on earth haven’t you figured out why your library behaves like this, it’s pretty frustrating and I’ll chose to revert to the older way of fetching data 😡😡😡😡😠😠

One thing to remember if you’re in the MSW/Testing land - set retry to 0 during testing.

Remember that Query intentionally backs off over a period of time to retry searching, upwards of a couple of seconds. This is a good thing, as it leads to better UX.

As a result, my tests were failing until I did this.

@balteo from what I can see, you are not “waiting” until the request is complete - you’re just rendering the form, and then expect the options to instantly be in there. But that’s not how it works. you need to wait until the request is completed. Adding something like:

expect(await screen.findByText(/accommodation/i)).toBeInTheDocument()

before actually trying to select it should work. However, I am also seeing this in the logs:

Error: Error: connect ECONNREFUSED 127.0.0.1:80

I don’t see anything that actually sets up msw. Have you read my blog post about that topic?

Once I add msw setup like described here:

things start to work, logging is:

  console.log
    categories:  []

      at MyForm (src/components/form/form.tsx:15:13)

  console.log
    isLoading:  true

      at MyForm (src/components/form/form.tsx:16:13)

  console.log
    categories:  [
      { id: 1, name: 'Personals' },
      { id: 2, name: 'Accommodation' },
      { id: 3, name: 'Employment' }
    ]

      at MyForm (src/components/form/form.tsx:15:13)

  console.log
    isLoading:  false

so nothing is “stuck in loading” anymore.

The next error is then:

Cannot select multiple options on a non-multiple select

So yeah, that’s something in the test / component itself, but reducing it to a single select makes the test pass. Here is the final code that worked for me in form.test.tsx:

import { setupMyForm } from '../../../test/setup-form';
import {server} from '../../../test/server'
import {screen} from '@testing-library/react'

describe('tests', () => {
    beforeAll(() => server.listen())
    afterEach(() => server.resetHandlers())
    afterAll(() => server.close())

    test('should submit form', async () => {

        const {
            renderForm,
            changeCategorySelect,
        } = await setupMyForm();

        renderForm();
        expect(await screen.findByText(/accommodation/i)).toBeInTheDocument()
        await changeCategorySelect(['Accommodation']);
    });
})

@TkDodo I tried to reproduce the issue on sandbox but it’s not happening, maybe it’s related to react native specifically. I will create an example repo of react native project and try to reproduce the problem on it, I will share it with you soon.

@TkDodo I am also facing the same issue and stuggling to reproduce it.

@ivillarreal91 I’m seeing this as well with latest, were you able to find a solution? Using useQuery in one component and useQueries with the same key in another component causes the useQuery to get stuck. Going to try to reproduce in a CSB.

Hello everyone!!!

Has anyone experienced the same behavior but now with useQueries hook? it doesn’t return data and gets stuck in loading randomly in the tests. I appreciate any support

"react": "^16.13.1"
"react-query": "^3.13.4"

I forgot to add more info: I’m mounting a lot of components (50) that use this useQuery with Infinity staleTime and I don’t have configured retry neither. I’m going to try to reproduce it in a sandbox.