Bug: useSyncExternalStore update not batched within unstable_batchedUpdates
Steps To Reproduce
- schedule two updates using "default priority" scope (eg. from within setTimeout)
- let one of the updates be handled through
useSyncExternalStoreand let the other one be handled through regularsetState
Link to code example:
https://codesandbox.io/s/interesting-chatterjee-9ed8hj?file=/src/App.js (without unstable_batchedUpdates)
https://codesandbox.io/s/prod-glitter-51vwm1?file=/src/App.js (with unstable_batchedUpdates)
The current behavior
The useSyncExternalStore update gets flushed and committed before the other one has a chance to be committed to the screen. This doesn't allow me to read the updated state of the committed DOM of the children components from within the Parent's effect
The expected behavior
I would expect to be able to "join" this sync update of the useSyncExternalStore somehow. Ideally, I wouldn't have to wrap both with unstable_batchedUpdates. It would be cool if I could just schedule a single update with the same priority. If I understand correctly multiple updates coming from different useSyncExternalStore updates can be batched together (it doesn't work like flushSync, so it doesn't literally immediately flush the scheduled update) - and I would just like to hop on that train with my second update.
I could live with the solution based on unstable_batchedUpdates but that doesn't seem to work either.
Andarist pointed out this is likely the cause of https://github.com/reduxjs/react-redux/issues/1912
unstable_batchedUpdates is a way to deprioritize an update by delaying it. The default priority is even more delayed and more batched than unstable_batchedUpdates. So unstable_batchedUpdates is a noop in React 18.
If you need the consistency you need to compromise - by making your updates less batched and flush earlier than they otherwise would - using flushSync.
That's the compromise of using useSyncExternalStore. To preserve consistency with external mutable store you have to make it less batchable - less delayed, than other forms of updates.
So
unstable_batchedUpdatesis a noop in React 18.
Cool, that's the first time I'm seeing this. Is the same true for unstable_batchedUpdates from react-native @sebmarkbage ?
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
bump
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
BUMP!
This is fixed in the RC and has been fixed in canary for awhile. We now flush default with all other sync updates.
https://codesandbox.io/s/stupefied-julien-6fysc9?file=/package.json
If I'm missing something let me know and I'll re-open.