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 for #109 #110

Merged
merged 1 commit into from
Dec 17, 2020
Merged

fix for #109 #110

merged 1 commit into from
Dec 17, 2020

Conversation

parisholley
Copy link
Contributor

@parisholley parisholley commented Dec 17, 2020

see the discussion here on how a similar issue affects all react libs for the most part:

apollographql/apollo-client#5870 (comment)
apollographql/apollo-client#6661

effectively, under normal circumstances, useEffect should only be invoked whenever values change, however when react-fast-refresh is active, the dependencies for useEffect are ignored and it is invoked again, allowing us to check if things are out-of-sync.

i'm unsure if this approach will affect benchmarks or not.

@@ -530,7 +530,24 @@ export function useState<S>(
RootPath,
() => setValue({ state: value.state }),
value.state);
React.useEffect(() => () => value.state.destroy(), []);
const renders = React.useRef(0);
Copy link
Owner

Choose a reason for hiding this comment

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

Nice clever fix. Yes, it will impact the performance, unfortunately. However, there is a way around it. Define module-global isDevelopment boolean flag and execute the proposed code only when it is true, otherwise keep the original one under release/production mode. And please let me know if tests are passing with it (I understand they should be). And I will merge after (if you complete it within next 12 hours, I will merge it today, otherwise only after New Year holidays :) )


return () => {
if (capture !== renders.current) {
// do not destroy state if a third party (eg: react-fast-refresh) has restored it on re-render
Copy link
Owner

Choose a reason for hiding this comment

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

Please add link in comments to this page: apollographql/apollo-client#5870 (comment)
very useful

@avkonst avkonst merged commit f488624 into avkonst:master Dec 17, 2020
@avkonst
Copy link
Owner

avkonst commented Dec 17, 2020

I will integrate it and finalize before leaving today. Thanks

@parisholley
Copy link
Contributor Author

thanks for getting this merged so quickly! I finally got tired of hard refreshing the page all the time... :)

as a note, i realized after the pull that using useMemo technically isn't a guarantee, so i used a locking mechanism instead:

parisholley@8b4f71d

i'm not sure how likely the original implementation would be a problem

@avkonst
Copy link
Owner

avkonst commented Dec 18, 2020

I do not think your lock implementation is right, because it essentially blocks state destruction after any rerender, hotreload or after setState call.

@parisholley
Copy link
Contributor Author

why do you say that? the useRef is persisted between rerender/reload/setstate, and because i removed the [] on the useEffect, it is effectively run after every render, removing the lock. i can't think of a circumstance in which the lock will have contention outside of hotreload, unless there is some behavior that can cause a render to happen multiple times before the useEffect is invoked.

@avkonst
Copy link
Owner

avkonst commented Dec 18, 2020

I missed that useEffect goes on every rerender. Now I do not understand what sequence of events would cause the lock to be true on effect destruction callback?

@avkonst
Copy link
Owner

avkonst commented Dec 18, 2020

Is the following sequence happens on hot reload?

  • rerender component (run the function) -> lock becomes true
  • call effect desturction callback -> does nothing because of the lock == true
  • call effect init callback -> resets the lock to false again

@avkonst
Copy link
Owner

avkonst commented Dec 18, 2020

If you are 100% sure it is the case and would like the improved version, please submit pull request again. I doubt I will have time today to merge it, but will be able to come back to it after the holidays break...

@avkonst
Copy link
Owner

avkonst commented Jan 8, 2021

I have integrated your latest proposal. Released in 3.0.3. Let me know how it goes.

@parisholley
Copy link
Contributor Author

works well 👍

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