-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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 subscriber being overwritten #85
Conversation
Thanks, interesting solution using Array.filter! 🙂 |
made a patch release |
I think there might still be an issue with concurrent mode. A component can unmount between another component's My hunch is that we need to avoid compressing the array when there is a pending index, although tracking this is tricky with React Suspense. |
@paulshen I think you're right. The problem with waiting on a pending index is a component can be called during the render phase but interrupted before React renders it in the DOM. We'd have an always-pending index and never be able to compress the subscribers array. I want to get away from doing anything during the render phase and only use Unfortunately,
We could have two arrays for subscribers, one that is sorted and one for holding new ones:
Then we reverse iterate over the new array and add the values to the sorted one. I don't know how to detect when to do this. It has to be done after React flushes effects. Maybe a combination of |
I don't know if there is a solution here (yet) 😞It feels like the root fix is having a Redux has an interesting solve for its |
I don't expect a useEffect variant like that to ever exist but it would solve our issue. It seems like the first useEffect callback is called after all useLayoutEffects callbacks are called. At least, this is the behavior for react-dom. I wonder if useLayoutEffect can be used to add subscribers to a When we want to call all subscribers, we would just call all The problem with this solution is it's dependent on the reconciler's behavior. |
@jhgg
Should fix #84
Here was the problem:
setState
is called before the subscriber object is added tosubscribers
array (between render phase anduseLayoutEffect
).subscribers
array is made dense, changing the length of the array and indices of subscribers.subscribers
array at wrong index, overwriting a valid subscriber.I moved the code that makes
subscribers
a dense array into the "unmount" phase (return function ofuseLayoutEffect
callback).