Skip to content

Commit 687ba4d

Browse files
committed
act: Bypass microtask for "default sync" updates
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 d7dce57 commit 687ba4d

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

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

Lines changed: 8 additions & 1 deletion
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

Lines changed: 8 additions & 1 deletion
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)