-
Describe the bug To Reproduce
Expected behavior Desktop (please complete the following information):
|
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 3 replies
-
do you expect In fact, if I remove the So I think this is more about how react batches updates together in event callbacks, but not outside of it: You setting enabled to false and then true in the same event handler might lead react to discard that setState altogether, because it happens in the same event handler. On the other hand, when called from outside, react doesn't do that. Now it disables the query, calls refetch (which doesn't do anything because of
further, if you all in all, this looks like the expected behaviour of how react batches updates, and I don't think there's anything react-query can do about it ... |
Beta Was this translation helpful? Give feedback.
-
FYI, React 18 will bring some changes to automatic batching, in which case it should work out of the box in more situations: reactwg/react-18#21 The discussion also explains quite well how it works in current v17, and also shows that your two setStates to setEnabled will be batched in synchronous functions. I don't think it would affect this situation though, because you have one setState before the async action, and then another one after it. So they can't be batched together, because an async action can take quite some time to complete :) |
Beta Was this translation helpful? Give feedback.
-
I am purposely disabling the query in the example, and also making refetchActive as false to control when the new request goes out - onclick of the button for this particular example. Essentially trying to trigger a refetch (without using the refetch of useQuery) every time the component renders after a reload button push. Initially it is disabled to start off with. It will get enabled after the 1st time you hit reload. The request goes out as expected. Reloading after that, still triggers a re-render of the component (irrespective of being batched or not, just the amount of re-renders change) as you can see from the logs. However this time the request doesn't go out again despite the fact that there is invalidateQueries in there. If react batched the updates and determined nothing really changed it would not trigger a re-render, which you can try by just commenting out the 1st setEnabled(false). Then the component doesn't re-render. So it is coming down to the queryClient.invalidateQueries() line is not doing anything at all. Like the behavior of it being in there or not being in there is the same when using the reload button. And yeah since React18 will have batching outside of event handlers, wont this be an issue then? |
Beta Was this translation helpful? Give feedback.
-
BTW same issue if I use queryClient.removeQueries() instead of invalidate. I would have expected that if the query is enabled but invalidated or non existent after being removed, it would trigger a auto-refetch on the next render pass. I may be wrong if this is not the intended behavior. In my real example, I am setting refetchActive to false, only because I don't want the request to go out till the next render pass, because I have updated the state in that click handler with some params/data that the query should use before it re-fetches. Setting refetchActive to true would have triggered a refetch before the next render pass and with stale data. |
Beta Was this translation helpful? Give feedback.
-
Another example https://codesandbox.io/s/silent-firefly-tcn4m?file=/src/index.js
After the 1st load/render, the API call goes out as expected. Now using the console if I do
The API call still doesn't go out |
Beta Was this translation helpful? Give feedback.
-
no, that's not what invalidation is doing. react-query will never re-fetch just because you re-render. staleTime defaults to zero, so all queries are instantly "stale" per default. invalidation marks a query as stale, and it automatically re-fetches active queries (an active query is a query that is currently used by useQuery) right away (not in the next render cycle or so). But since you set This also explains the last example. Invalidating the query and triggering a re-render will not get you a refetch, because again, that's not what invalidation means. I think it's time you take a step back and tell us about your use-case: What do you want to achieve instead of what code you already have that isn't working. If all you want to do is have a disabled query and then refetch when a button is clicked, there are other ways. If you want a lazy query, there are also other ways... Meanwhile, I'm converting this to a discussion because I'm convinced that there is no issue in react-query per se. |
Beta Was this translation helpful? Give feedback.
no, that's not what invalidation is doing. react-query will never re-fetch just because you re-render. staleTime defaults to zero, so all queries are instantly "stale" per default.
invalidation marks a query as stale, and it automatically re-fetches active queries (an active query is a query that is currently used by useQuery) right away (not in the next render cycle or so). But since you set
refetchActive: false
, all that the invalidation is doing is setting the query to stal…