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: clear refresh timer on effects change and check it on starting new timer #853

Merged
merged 3 commits into from
Jan 3, 2021

Conversation

huozhi
Copy link
Member

@huozhi huozhi commented Jan 2, 2021

Fix #852

Description

swr/src/use-swr.ts

Lines 687 to 697 in 00c5847

// Read the latest refreshInterval
if (configRef.current.refreshInterval) {
timer = setTimeout(tick, configRef.current.refreshInterval)
}
}
if (configRef.current.refreshInterval) {
timer = setTimeout(tick, configRef.current.refreshInterval)
}
return () => {
if (timer) clearTimeout(timer)
}

when timer is been cancelled, but to the timer procedure, it cannot know if the last timer is cancelled. so it started a new timer again.

steps:
start timer > revalidate > timer is cancelled due to effects > but still start a new timer (with legacy revalidate).

Changes

mark timer as null when cancel it and the cancel state is kept as condition. then swr can avoid to start a new timer again.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jan 2, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a8d3549:

Sandbox Source
SWR-Basic Configuration
SWR-States Configuration
SWR-Infinite Configuration
youthful-elgamal-g1n4u Issue #852

Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

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

This is a good catch! Indeed there's an async process inside tick so it's not safe to guarantee that cancel is safe. But I don't understand why you need an object to bind the latest timer value to the closure, I suppose just timer would work too (by checking if it's null on line 688)?

@huozhi huozhi requested a review from shuding January 2, 2021 16:58
@huozhi
Copy link
Member Author

huozhi commented Jan 2, 2021

@shuding yeah re-test it, it works well! thanks

Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

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

Thank you so much 😊

@promer94
Copy link
Collaborator

promer94 commented Jan 2, 2021

It seems i am a little late 😂. I just find a solution

    // Read the latest refreshInterval and make sure the key is not changed
      if (configRef.current.refreshInterval && key === keyRef.current) {
        timer = setTimeout(tick, configRef.current.refreshInterval)
      }

@huozhi
Copy link
Member Author

huozhi commented Jan 2, 2021

@promer94 that's a very good point! but the effects clean up can due to several change, we cannot guarantee the key will be the only factor in the long time.

@promer94
Copy link
Collaborator

promer94 commented Jan 2, 2021

Another problem is that the actual refreshInterval is the response time + refreshInterval option

We should mention this in the docs

@shuding
Copy link
Member

shuding commented Jan 2, 2021

Seems some interval tests are failing

test/use-swr.test.tsx Outdated Show resolved Hide resolved
@huozhi huozhi changed the title fix: keep refresh timer refrence fix: clear refresh timer on effects change and check it on starting new timer Jan 3, 2021
@shuding shuding merged commit 393af2e into vercel:master Jan 3, 2021
@huozhi huozhi deleted the fix-refresh-timer branch January 3, 2021 05:28
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.

SWR keeps refreshing with old bearer token
3 participants