Closed vsaarinen closed 3 years ago
@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
@nawfalhaddi if its related to 4 useQuery queries running in parallel, can you reproduce this in a sandbox?
Btw this is on a react native project
Are all problems posted in this issue related to react native?
@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.
could this be related to https://github.com/tannerlinsley/react-query/issues/3332 ?
@TkDodo I am experiencing the same issue on version 3.24.4 - isLoading
gets stuck on true. I'm using React Native and this happens to me randomly (but only on app startup). It seems to happen about every 1 in 10 or 20 times, so is quite difficult to replicate.
Any update on this?
I also have the same question as @nawfalhaddi:
is there a way to force a useQuery to check the observer again?
Hey y'allz. I've been dealing with this for 8 hours myself and this is my story:
My query that's stuck in loading has an enabled property, and I had a race condition where:
For me I just needed to call resetQueries, but the race condition made the problem intermittent and it would only happen on app startup. Hopefully it helps somebody
I'm experiencing the same issue on version 3.38.0. The useQuery
call returned { data: undefined, error: null, isLoading: true }
once and never got updated. It seems to only happen when my Jest tests are run in CI environment with multiple workers (with --maxWorkers=4
flag). It doesn't happen on my local machine, nor when I set --maxWorkers=1
(single worker mode). DK if the info helps.
It's then fixed by adding --silent
flag to Jest. Maybe it's noting to do with react-query
itself, but the logs slowing down the thread and finally causing the waitFor
util to timeout.
imo it doesn't make much sense if more people keep commenting on this closed issue from over a year ago. If you have a consistent reproduction, or any reproduction for that matter, please open a new issue. There isn't much I can do otherwise I'm afraid.
Hi @TkDodo
I have implemented a small application that reproduces the issue described in this discussion. Here is the repo: https://github.com/balteo/react-query-issue-reproduction
Just git clone the repos and yarn install
and yarn run test
Please let me know if I can help further.
Kind regards
@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 Thanks a lot for your detailed reply!
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?
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.
I renamed the port-to-v3 label as port-to-v4, that was probably not a good idea, sorry.
code is quite different now, I would need to see a codesandbox reproduction that fails on v4 please.
the code path you're showing has been removed in a later v3 version to ensure concurrent rendering capabilities:
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();
ok sheesh i think i found the issue. With Multiple queries comes multiple isLoading
the part of the component that depended on the second query was rendering too soon causing the issue. So these multiple isLoading
s and checking of data
for each of these queries will need to be handled individually. Any early rendering causes the query status to stay stuck (or rather give the illusion i should say).
I am experiencing this issue consistently in a larger project with
"@tanstack/react-query": "4.26.0",
"react": "18.2.0",
"next": "13.2.3",
but only if react is running in strict mode.
Unfortunately I do not have a minimal repro example.
I am facing the same issue only in Cypress. (Edit: working in Playwright, switching to it)
Devtools indicate that the data is fresh but the loader is still loading (isFetching).
I am using react query for server state and redux for client state. Could be related
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
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.
We also faced the same issue where for some reason some users were not able to fetch the data properly.
On further debugging found the fetchStatus was always paused
. After going through docs, we passed the networkMode: always
and it worked fine this time. We also verified this by removing the networkMode config.
So this probably means something wrong is happening in the code when the default networkMode: on
value is set.
cc @TkDodo
NOTE: Using the latest version current: 4.35.3
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
Since navigator.onLine is broken, we've moved away from using it in v5
Thanks for the quick reply, will upgrade to v5.
I just needed to update to the new version of Chrome, now it's working.
macOS: Ventura 13.5.2 (Apple M1 Pro)
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 😡😡😡😡😠😠
We have a large number of users using the app, occasionally a few users encounter this issue where all the functions using react query get stuck at the loading stage, whereas direct calls using axios to the API work fine. The characteristic is that the loading is shown, but no requests seem to be made to the server. When we instruct the users to completely close the browser and reopen it, everything starts working normally again. It's quite strange.
"@tanstack/react-query": "^4.24.4"
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
});
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:
networkMode: 'offlineFirst'
to work around itIt'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 fromuseQuery
when that happens. If thefetchStatus
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 🤷
Thank you for responding, however, it happens randomly across different browsers including Edge, Brave, etc. I will try upgrading to v5.
edge and brave are both built on chromium ... they are the same thing and have the same behaviour / bugs in this regard
Firefox 120.0.1 (64-bit) still occurring M2 Mac, Sonoma 14.1.1
@117 on query v4 or v5? We haven't done anything on v4 - and also won't because the fix / workaround was a change in behaviour, so it's a breaking change
I've had the same problem for a while and haven't bothered to investigate until now. I've now figured out the reason which for me was that I called queryClient.reset()
on mount, as a side effect of resetting the client when the user signs out.
Here's a sandbox: https://codesandbox.io/p/sandbox/react-query-bug-sfm3fx?file=%2Fsrc%2FApp.tsx%3A16%2C2
I've also included the fix that worked for me, which you can toggle on/off using the useFix
flag in App.tsx.
Is this a bug in React Query or just bad implementation on my part? @TkDodo
@lundstromdavid it seems like you're clearing the cache while the query is in-flight, I don't know why you would do something like that. clear()
is not the same as resetQueries()
because clear does not inform observers about the change
@TkDodo Thanks for the reply! Should have read up more before. Although it does seem quite unintuitive for me that clear()
can stall in-flight queries in a loading state, but what do I know :man_shrugging:
can confirm this indeed happens with react: 18.2
, and @tanstack/react-query 4.36.1
on post
request when running jest
test with axios 1.6.2
and axios-mock-adapter 1.22.0
, still happens after upgrading @tanstack/react-query
to 5.17.19
, I can see the result in useQuery, but it never returns to the component, and the status
is always loading
; hence replaced @tanstack/react-query
with vanilla axios
for my data fetching part, and the failed test passes...
Also found a very hacky workaround if you don't want to replace @tanstack/react-query
with other libraries: basically just do a data fetching with axios-mock-adapter
in beforeAll
or beforeEach
, then run your regular test, and in your test block, do a data fetching with axios-mock-adapter
again... your test will then have about 1/2 chance of passing... super confusing bug
One thing you can try on v5 is to disable our batching and see if that helps:
import { notifyManager } from '@tanstack/react-query'
// invoke callback instantly
notifyManager.setScheduler((cb) => cb())
see: https://tanstack.com/query/latest/docs/reference/notifyManager#notifymanagersetscheduler
I would like to recommend changing the default setting of the networkMode configuration in React Query to 'always'. Given the library's widespread use, with over 2 million downloads per week, the current default setting may lead to significant issues.
Recently, we encountered a bug where the system did not make any network requests due to the networkMode being set to 'online'. This issue arose because the browser's navigator.onLine API inaccurately reported the network status as offline, even though the connection was active. The impact of this bug is particularly severe as it can cause key pages to remain stuck on a loading screen without any indication of the problem. Considering that React Query is a critical part of many projects, such errors can have drastic consequences, including potential job losses, especially if key stakeholders encounter these issues firsthand.
It can be challenging to identify this issue without delving into the source code, making it a silent but deadly problem. To enhance reliability and prevent such problematic scenarios, I strongly urge you to consider setting the default networkMode to 'always'. This change would ensure that network requests are made regardless of the navigator.onLine status, thus providing a more consistent and dependable user experience.
Thank you for considering this suggestion. I believe it will significantly improve the robustness of React Query and safeguard many developers and businesses from facing similar issues.
One thing you can try on v5 is to disable our batching and see if that helps:
import { notifyManager } from '@tanstack/react-query' // invoke callback instantly notifyManager.setScheduler((cb) => cb())
see: https://tanstack.com/query/latest/docs/reference/notifyManager#notifymanagersetscheduler
Hey @TkDodo I was facing identical issue. This helped when running cypress tests. Is there any other way to achieve this without changing global configuration?
you can set the scheduler inside cypress tests only.
Hey @TkDodo Thank for quick reply.
However, adding it like this
it('Cypress test demo', () => {
notifyManager.setScheduler((cb) => cb());
// Test logic
});
or this
notifyManager.setScheduler((cb) => cb());
...
it('Cypress test demo', () => {
// Test logic
});
Doesn't work. Only works if directly added to the component
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 withisLoading
astrue
anddata
asundefined
. Reverting back to react-query 2 fixed the problems.Most of the requests in our Cypress tests are stubbed using
cy.server
andcy.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:
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):
Additional context Happens on both Cypress version 5.3.0 and 6.2.1.