Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix refetchInterval infinite loop #404

Merged

Conversation

cherniavskii
Copy link
Contributor

Use queryRef to avoid infinite loop in refetch interval effect.

Fixes #399

@@ -89,6 +89,7 @@ export function useBaseQuery(queryKey, queryVariables, queryFn, config = {}) {

// Handle refetch interval
React.useEffect(() => {
const query = queryRef.current
if (
config.refetchInterval &&
(!query.refetchInterval || config.refetchInterval < query.refetchInterval)
Copy link
Contributor Author

@cherniavskii cherniavskii Apr 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think query.refetchInterval name is confusing and should be renamed to query.refetchIntervalId, since it actually stores interval ID.

Then config.refetchInterval < query.refetchInterval comparison doesn't make sense to me.

As well as !query.refetchInterval check, since query.refetchInterval will be always undefined due to cleaning function returned by useEffect.

@tannerlinsley thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the idea was that if a user passed different intervals for the same query but on different instances, then the shortest interval time would override the longer one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should work as you described now!

@cherniavskii
Copy link
Contributor Author

Wanted to add a unit test fot this case, but it involves dealing with timers, which can be tricky and I did't want to invest my time into this right now.
So I've created an issue - #405
Please add "help wanted" label to it :)

@@ -110,7 +110,7 @@ export function makeQueryCache() {

if (query) {
Object.assign(query, { queryVariables, queryFn })
Object.assign(query.config, config)
query.config = { ...query.config, ...config }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tannerlinsley

Object.assign was causing a bug. Consider this situation:

  1. first instance of useQuery creates a new query and sets query.config pointer to config object
  2. second instance of useQuery with different config object takes query from cache
  3. Object.assign mutates first instance query.config object

Now as I think about it, maybe we should copy query config in the first step instead of referencing it?
Either way, it should be good now.

But that was super tough to debug :D

@tannerlinsley
Copy link
Collaborator

Yes!! This was a total doozy

@tannerlinsley tannerlinsley merged commit 43e223a into TanStack:master May 1, 2020
@cherniavskii cherniavskii deleted the fix/refetchInterval-infinite-loop branch May 1, 2020 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants