-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: state update warnings, incomplete hooks reactivity #135
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
Conversation
This commit adds a useCancel() utility function, which allows to manage the cancelled state of a query. It automatically calls its cancellation callback when the component unmounts, and can be manually called to invalidate it in other cases (typically by returning it in any useEffect() calling the query function defining its callback). This utility has been added to many hooks in the library, which removes warnings caused by the library trying to update state on unmounted components, or updating state in outdated render contexts. Note that since these callbacks are also returned by the hooks and can be called to fetch results, they never interrupt when cancelled: instead, they just stop updating the state. This commit also makes sure some useEffect() hooks react to changes on all the dependencies they are using. Some unnecessary cancel checks have also been removed from these useEffect() hooks.
|
|
Someone is attempting to deploy a commit to a Personal Account owned by @tmm on Vercel. @tmm first needs to authorize it. |
| let didCancel = false | ||
| if (didCancel) return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didCancel will always be false here, so the if (didCancel) is unnecessary.
| return () => { | ||
| didCancel = true | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this can be safely removed since the only use of didCancel here is in the if check right after its definition.
|
|
||
| return () => { | ||
| didCancel = true | ||
| if (!skip && cacheBuster) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cacheBuster is always truthy since it starts at 1, this is just to make ESLint happy.
|
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/zoo/wagmi/CRpMmtwzcyiaTnYXmPqurPocZgJq |
|
Looks great and will do a proper review in a bit! You might also be interested in checking out #85 |
|
Thanks! 🤗 I just opened a discussion that also takes inspiration from React Query (for |
|
Looking good! Waiting until the RFC drops (sometime this week) for the discussion (#85) I linked above since that could have some implications for how this is set up. |
49eadcb to
4ce2969
Compare
|
Regarding #162 (comment): I am not sure what the strategy should be for the changes I suggest in #162, since this PR is not merged yet (I would rather have all the hooks updated at once rather only this one), and #153 will also be an opportunity to fix these issues in a different way, so we might as well want to keep going with the same structure in the meantime. An alternative approach could also be to fix the /cc @tmm @shunkakinoki |
This PR prevents state to be set on unmounted or outdated render contexts by refactoring the hooks around a new
useCancel()utility hook, which allows to manage the cancelled state of a query. It automatically calls its cancellation callback when the component unmounts, and can be manually called to invalidate it in other cases (typically by returning it in anyuseEffect()calling the query function defining its callback).This utility is used by multiple hooks, which removes the warnings caused by the library trying to update state on unmounted components, or on outdated render contexts.
Note that since these callbacks are also returned by the hooks and can be called independently to fetch results, they don’t interrupt when cancelled. Instead, they just stop updating the local state.
These changes also ensure some
useEffect()hooks react to changes on all the dependencies they are using, removing the need to disable thereact-hooks/exhaustive-depsESLint rule. Some unnecessary cancel checks have also been removed from theseuseEffect()hooks.Note on tests: I tried different ways to test this, but I couldn’t find a reliable way to check if React emits a warning if the state of an unmounted component is set.
@tmm let me know what you think!