-
Notifications
You must be signed in to change notification settings - Fork 18
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
Inconsistent behavior based on the order that components are rendered (React) #64
Comments
Thanks for the complete and detailed report, this is a nicely put together sandbox. The problem is a different You can further simplify the reproduction by replacing an atom with just a random number, for example: https://codesandbox.io/p/sandbox/focused-oskar-9z7ytd?file=%2FApp.tsx Looks like I need to add a test case to ScopeProvider.test.tsx for this particular rendering case. This should probably be tested across both |
@loganvolkers Thanks for the speedy reply! It seems that you linked back to the original CodeSandbox that I posted, but yeah it can be reproduced without atoms. It is easy to enable/disable ScrictMode in the CodeSandbox in index.tsx. FWIW the issue happens in both cases in my tests. |
Reproduced via test cases in #66 across both strict mode and non-strict mode. |
The reason for this relates to how molecule values get created and possibly discarded. This behaviour was added to comply with React strict mode. Injectors will create values, but won't persist or share them until a subscription is started. This means that during initial render, you might have 2 different values for a base molecule, with one being discarded based on when Later on during the subscription lifecycle (or component lifecycle in React) then a molecule will be "mounted", which will save it's value to the cache. That is, unless there's already a value in the cache, in which case the value will be discarded and we'll just grab the value from the cache. This is what happens when we start a subscription for a derived molecule first. It will store the base value in the cache, and then other uses of the base molecule will be discarded and replaced with the cache value. The problem for this case is that if we start the subscription for the base molecule first, then when the derived molecule is used, it checks if it's the right value, but it never checks if it's dependencies are still up-to-date. So it never gets discarded. To fix this, we need to make sure that when a derived molecule is used, it always checks that it has the latest value of all of it's dependencies. If it isn't up to date, then the derived molecule should be re-run. I have a fix for this in the |
Just saw this linked to on Twitter. Y'all may be interested in looking at https://github.com/isographlabs/isograph/blob/main/libs/isograph-react-disposable-state/src/useCachedPrecommitValue.ts, which allows you to execute some function once during the initial render of a component, and reuse that value going forward. (That is purposefully a vague statement, as the library is quite generic. So, that function could be "create a base molecule" or "start a subscription".) This can (probably) solve the issue articulated here. |
Thanks for noticing and commenting @rbalicki2 -- it looks like you're solving a similar problem! Bunshi has two internal injector methods:
To ensure no memory leaks, anything that calls Since you're the author of I had started building a similar timeout-based eviction policy into Bunshi V2.1 but I ran into problems getting the test suite to pass with the subtle change in behaviour. |
Yeah, happy to dive into more detail! Do you want to hop on a call at some point to discuss? Happy to run you through this. The easiest way to coordinate that would be to DM me @statisticsftw on Twitter or email me ([email protected]). Anyway, I just wrote up an extremely detailed description of how |
Thanks for the write-up @rbalicki2 and the offer. I may just hit you up on it on your help via a call. In theory the approach in That said, it seems like there would still be the possibility of no temporarily retained value being present, in the case where components take too long. In this case, we would still need to handle our graph invalidation case. Given this situation, we may still need to do a deep refresh (like in #66) as a safety measure. I'm going to keep pulling on the approach in #66 to solve this front and center bug in Bunshi. The FutureI've created a new discussion around temporary retain in #68 to tackle some of the possibilities there. |
Hi Logan, is there any update on this? I would like to add scoping to ≈100 atoms that are currently global. I am very happy with bunshi generally, and I would like to use it for this purpose as well, but it would be a complex nested molecule structure. This bug would inevitably cause many headaches. |
With nested molecules and multiple ScopeProviders, the order that components are rendered changes the behavior in a strange way.
Reproduction on CodeSandbox
https://codesandbox.io/p/sandbox/focused-oskar-9z7ytd?file=%2FApp.tsx
Setup
Bug
The first 2 names are synced together. The third and fourth names are not synced to anything.
Notes
The text was updated successfully, but these errors were encountered: