-
Notifications
You must be signed in to change notification settings - Fork 104
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
Subtle caveat with async methods #184
Comments
This seems like a very valid issue, luckily the fix will probably be easy and will be included in the next release. Easy State is wrapping nested store data during get-time if the immediate parent object is already observed by at least one We will remove this optimization in the next release which will fix this issue (and let us do some other cool things). It should not cause any noticeable performance changes for normal use cases. |
Great. I was thinking over the problem more last night and this is the same conclusion I came to. Thanks. As soon as the code is in git I would be happy to test it. |
This will be included in the 7.0.0 release. You can try it now with |
Thanks. I have confirmed that this works in my actual application too. You are awesome. I am curious, what change actually fixes the issue? It wasn't clear to me from the commits. |
React Easy State version: 6.3.0
Platform: browser
There is a subtle caveat when state is modified after an async function, or in any situation where the code is called asynchronously outside a React render cycle.
If a reference to new state is held across an async boundary then the new state is not observed and changes to it do no trigger a re-render.
Here is a code snippet that shows the problem. The key is that a local variable
counter
is used after the async call. If it is used before the async call it works correctly, or ifcounterStore
is used after the call to get a reference to the value from the store again then it also works correctly.It seems like you could just say "always reference the store when updating a value", but that is very hard to do, especially with complex code. The same above was created by removing all of the complexity and nested function calls that was otherwise hiding the problem.
This is disappointing because it undermines the awesome promise of react-easy-state. I think it is worth trying to solve so code like this can work transparently.
Theory of the problem
I think the problem exists because of this sequence:
addCounter
is called from an event handler, so changes to the state are proxied (observed), but the new values themselves are not wrapped in a proxy.counter
is not a proxied variable, even though it appears to have been correctly read from the store.counterStore.counters
array and the render doesn't happen until after the function exits (because React is batching the renders).Second variation on problem
The same problem can be triggered using
setTimeout
too:The text was updated successfully, but these errors were encountered: