Skip to content

Commit 27c9c95

Browse files
authored
act: Bypass microtask for "default sync" updates (#21740)
When wrapping an update in act, instead of scheduling a microtask, we can add the task to our internal queue. The benefit is that the user doesn't have to await the act call. We can flush the work synchronously. This doesn't account for microtasks that are scheduled in userspace, of course, but it at least covers React's usage.
1 parent 8426bb6 commit 27c9c95

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,14 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
692692
}
693693
if (supportsMicrotasks) {
694694
// Flush the queue in a microtask.
695-
scheduleMicrotask(flushSyncCallbacks);
695+
if (__DEV__ && ReactCurrentActQueue.current !== null) {
696+
// Inside `act`, use our internal `act` queue so that these get flushed
697+
// at the end of the current scope even when using the sync version
698+
// of `act`.
699+
ReactCurrentActQueue.current.push(flushSyncCallbacks);
700+
} else {
701+
scheduleMicrotask(flushSyncCallbacks);
702+
}
696703
} else {
697704
// Flush the queue in an Immediate task.
698705
scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,14 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
692692
}
693693
if (supportsMicrotasks) {
694694
// Flush the queue in a microtask.
695-
scheduleMicrotask(flushSyncCallbacks);
695+
if (__DEV__ && ReactCurrentActQueue.current !== null) {
696+
// Inside `act`, use our internal `act` queue so that these get flushed
697+
// at the end of the current scope even when using the sync version
698+
// of `act`.
699+
ReactCurrentActQueue.current.push(flushSyncCallbacks);
700+
} else {
701+
scheduleMicrotask(flushSyncCallbacks);
702+
}
696703
} else {
697704
// Flush the queue in an Immediate task.
698705
scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);

0 commit comments

Comments
 (0)