Skip to content

useAsync with deferFn calls run with stale props if component rerendering #69

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

Closed
Hianz opened this issue Aug 2, 2019 · 2 comments
Closed

Comments

@Hianz
Copy link

Hianz commented Aug 2, 2019

If my deferFn is defined outside of my component (which uses useAsync), the props parameter is stale after the second render of the Child component if the props of the Parent component change.
If the deferFn is declared inside the component everything works as expected.

Here is a codeSandbox that shows the issue:
https://codesandbox.io/s/react-async-stale-props-lq141
(Clicking 2 times of 'Click me twice' & after that on the Start run() button, the console will show the stale props.)

Interestingly enough if i change the options parameter inside useAsync.js to prevOptions.current everything works as expected. After the second render if the Parent props change, options has stale props from the previous render and prevOptions.current has the correct ones.

//options -> stale, prevOptions.current -> correct ones
return start(() => deferFn(args, options, abortController.current)).then(handleResolve(counter.current), handleReject(counter.current));
@ghengeveld
Copy link
Member

Thanks for reporting. I've setup a unit test which confirms this behavior. The issue is with useMemo around the returned value object. It doesn't recalculate on all props, only on a few specific ones. Changes to user-defined props such as id in your case do not trigger a recalculation of the memoized value, which makes it return an old version of run with an old props object in its closure. Unfortunately I can't simply pass props as a useMemo trigger, because that would be the same as omitting useMemo altogether. I'm now thinking of storing props in a ref and have run use that value. Because it's a mutable reference it would always point to the same (updated) value.

@ghengeveld
Copy link
Member

ghengeveld commented Aug 5, 2019

Released in v7.0.6

Thanks again for reporting, and for providing a reproduction scenario!

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

No branches or pull requests

2 participants