Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@bpierre
Copy link
Contributor

@bpierre bpierre commented Feb 5, 2022

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 any useEffect() 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 the react-hooks/exhaustive-deps ESLint rule. Some unnecessary cancel checks have also been removed from these useEffect() 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!

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.
@changeset-bot
Copy link

changeset-bot bot commented Feb 5, 2022

⚠️ No Changeset found

Latest commit: 6ec06cf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Feb 5, 2022

Someone is attempting to deploy a commit to a Personal Account owned by @tmm on Vercel.

@tmm first needs to authorize it.

Comment on lines -54 to -65
let didCancel = false
if (didCancel) return
Copy link
Contributor Author

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.

Comment on lines -63 to -75
return () => {
didCancel = true
}
Copy link
Contributor Author

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) {
Copy link
Contributor Author

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.

@vercel
Copy link

vercel bot commented Feb 5, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/zoo/wagmi/CRpMmtwzcyiaTnYXmPqurPocZgJq
✅ Preview: https://wagmi-git-fork-bpierre-cancel-queries-zoo.vercel.app

@tmm
Copy link
Member

tmm commented Feb 6, 2022

Looks great and will do a proper review in a bit!

You might also be interested in checking out #85

@bpierre
Copy link
Contributor Author

bpierre commented Feb 6, 2022

Thanks! 🤗

I just opened a discussion that also takes inspiration from React Query (for refetch()): #140

@tmm
Copy link
Member

tmm commented Feb 8, 2022

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.

@tmm tmm force-pushed the main branch 4 times, most recently from 49eadcb to 4ce2969 Compare February 10, 2022 02:08
@bpierre bpierre changed the title Prevent state to be set on unmounted or outdated render contexts Fix “can't perform a react state update on an unmounted component” warnings Feb 13, 2022
@bpierre bpierre changed the title Fix “can't perform a react state update on an unmounted component” warnings fix: state update warnings, incomplete hooks reactivity Feb 13, 2022
@bpierre
Copy link
Contributor Author

bpierre commented Feb 13, 2022

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 setState() calls so the library stops emitting warnings, and remove the unneeded didCancel checks, but leave the dependencies fix for later since this will alter the hooks behavior.

/cc @tmm @shunkakinoki

@tmm
Copy link
Member

tmm commented Feb 13, 2022

Agree! #153 will be great, but in the meantime, this is a nice improvement. Once merged in, #162 can follow along.

@tmm tmm merged commit e87538c into wevm:main Feb 13, 2022
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.

2 participants