diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
index 67d1a29f0ab03..2ad221d5fbcb6 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
@@ -380,6 +380,7 @@ describe('ReactDOMServerPartialHydration', () => {
resolve();
await promise;
Scheduler.unstable_flushAll();
+ await null;
jest.runAllTimers();
// We should now have hydrated with a ref on the existing span.
diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
index fea9d79b4735d..a361e55a7f8fc 100644
--- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
@@ -488,6 +488,7 @@ describe('ReactDOMServerHydration', () => {
jest.runAllTimers();
await Promise.resolve();
Scheduler.unstable_flushAll();
+ await null;
expect(element.textContent).toBe('Hello world');
});
diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
index 36dbc704fc7cd..1c13e3a8fda90 100644
--- a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
+++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
@@ -16,6 +16,7 @@ import {__interactionsRef} from 'scheduler/tracing';
import {
enableSchedulerTracing,
decoupleUpdatePriorityFromScheduler,
+ enableSyncMicroTasks,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import {
@@ -23,6 +24,7 @@ import {
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from './ReactFiberLane.new';
+import {scheduleMicrotask, supportsMicrotasks} from './ReactFiberHostConfig';
const {
unstable_runWithPriority: Scheduler_runWithPriority,
@@ -144,13 +146,19 @@ export function scheduleSyncCallback(callback: SchedulerCallback) {
// the next tick, or earlier if something calls `flushSyncCallbackQueue`.
if (syncQueue === null) {
syncQueue = [callback];
- // Flush the queue in the next tick, at the earliest.
+
// TODO: Figure out how to remove this It's only here as a last resort if we
// forget to explicitly flush.
- immediateQueueCallbackNode = Scheduler_scheduleCallback(
- Scheduler_ImmediatePriority,
- flushSyncCallbackQueueImpl,
- );
+ if (enableSyncMicroTasks && supportsMicrotasks) {
+ // Flush the queue in a microtask.
+ scheduleMicrotask(flushSyncCallbackQueueImpl);
+ } else {
+ // Flush the queue in the next tick.
+ immediateQueueCallbackNode = Scheduler_scheduleCallback(
+ Scheduler_ImmediatePriority,
+ flushSyncCallbackQueueImpl,
+ );
+ }
} else {
// Push onto existing queue. Don't need to schedule a callback because
// we already scheduled one when we created the queue.
diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
index 1d309df4020f1..5c4451499ca5b 100644
--- a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
+++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
@@ -16,6 +16,7 @@ import {__interactionsRef} from 'scheduler/tracing';
import {
enableSchedulerTracing,
decoupleUpdatePriorityFromScheduler,
+ enableSyncMicroTasks,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import {
@@ -23,6 +24,7 @@ import {
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from './ReactFiberLane.old';
+import {scheduleMicrotask, supportsMicrotasks} from './ReactFiberHostConfig';
const {
unstable_runWithPriority: Scheduler_runWithPriority,
@@ -144,13 +146,19 @@ export function scheduleSyncCallback(callback: SchedulerCallback) {
// the next tick, or earlier if something calls `flushSyncCallbackQueue`.
if (syncQueue === null) {
syncQueue = [callback];
- // Flush the queue in the next tick, at the earliest.
+
// TODO: Figure out how to remove this It's only here as a last resort if we
// forget to explicitly flush.
- immediateQueueCallbackNode = Scheduler_scheduleCallback(
- Scheduler_ImmediatePriority,
- flushSyncCallbackQueueImpl,
- );
+ if (enableSyncMicroTasks && supportsMicrotasks) {
+ // Flush the queue in a microtask.
+ scheduleMicrotask(flushSyncCallbackQueueImpl);
+ } else {
+ // Flush the queue in the next tick.
+ immediateQueueCallbackNode = Scheduler_scheduleCallback(
+ Scheduler_ImmediatePriority,
+ flushSyncCallbackQueueImpl,
+ );
+ }
} else {
// Push onto existing queue. Don't need to schedule a callback because
// we already scheduled one when we created the queue.
diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
index 017c712bd814b..48ff50880f943 100644
--- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
@@ -598,12 +598,13 @@ describe('ReactExpiration', () => {
// second one.
Scheduler.unstable_advanceTime(1000);
// Attempt to interrupt with a high pri update.
- updateHighPri();
+ await ReactNoop.act(async () => {
+ updateHighPri();
+ });
- // The first update expired, so first will finish it without
- // interrupting. But not the second update, which hasn't expired yet.
- expect(Scheduler).toFlushExpired(['Sibling']);
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
+ // The first update expired
+ 'Sibling',
// Then render the high pri update
'High pri: 1',
'Normal pri: 1',
diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
index bf5503feb4902..4c7d308a9c909 100644
--- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
@@ -1792,7 +1792,7 @@ describe('ReactHooksWithNoopRenderer', () => {
it(
'in legacy mode, useEffect is deferred and updates finish synchronously ' +
'(in a single batch)',
- () => {
+ async () => {
function Counter(props) {
const [count, updateCount] = useState('(empty)');
useEffect(() => {
@@ -1807,10 +1807,12 @@ describe('ReactHooksWithNoopRenderer', () => {
}, [props.count]);
return ;
}
- act(() => {
+ await act(async () => {
ReactNoop.renderLegacySyncRoot();
+
// Even in legacy mode, effects are deferred until after paint
- expect(Scheduler).toFlushAndYieldThrough(['Count: (empty)']);
+ ReactNoop.flushSync();
+ expect(Scheduler).toHaveYielded(['Count: (empty)']);
expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
});
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
index f568191681b67..613fe89d63279 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
@@ -1400,6 +1400,10 @@ describe('ReactIncrementalErrorHandling', () => {
'BrokenRenderAndUnmount componentWillUnmount',
]);
expect(ReactNoop.getChildren()).toEqual([]);
+
+ expect(() => {
+ ReactNoop.flushSync();
+ }).toThrow('One does not simply unmount me.');
});
it('does not interrupt unmounting if detaching a ref throws', () => {
diff --git a/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js b/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
index e830fa2b24ddf..b3f14e6ad1efc 100644
--- a/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
@@ -98,8 +98,11 @@ describe('ReactOffscreen', () => {
>,
);
+
+ ReactNoop.flushSync();
+
// Should not defer the hidden tree
- expect(Scheduler).toFlushUntilNextPaint(['A', 'Outside']);
+ expect(Scheduler).toHaveYielded(['A', 'Outside']);
});
expect(root).toMatchRenderedOutput(
<>
diff --git a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
index 4292333293e82..ab9995d01cb5f 100644
--- a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
@@ -569,9 +569,11 @@ describe(
ReactNoop.render();
});
+ ReactNoop.flushSync();
+
// Because the render expired, React should finish the tree without
// consulting `shouldYield` again
- expect(Scheduler).toFlushExpired(['B', 'C']);
+ expect(Scheduler).toHaveYielded(['B', 'C']);
});
});
},
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
index de74c18e5ca6a..2cdc2621fbe9a 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
@@ -292,9 +292,11 @@ describe('ReactSuspenseList', () => {
>,
);
- await C.resolve();
+ await ReactNoop.act(async () => {
+ C.resolve();
+ });
- expect(Scheduler).toFlushAndYield(['C']);
+ expect(Scheduler).toHaveYielded(['C']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -304,9 +306,11 @@ describe('ReactSuspenseList', () => {
>,
);
- await B.resolve();
+ await ReactNoop.act(async () => {
+ B.resolve();
+ });
- expect(Scheduler).toFlushAndYield(['B']);
+ expect(Scheduler).toHaveYielded(['B']);
expect(ReactNoop).toMatchRenderedOutput(
<>
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
index d40f56380b7e8..b6e34104ad61f 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
@@ -310,7 +310,7 @@ describe('ReactSuspensePlaceholder', () => {
});
describe('when suspending during mount', () => {
- it('properly accounts for base durations when a suspended times out in a legacy tree', () => {
+ it('properly accounts for base durations when a suspended times out in a legacy tree', async () => {
ReactNoop.renderLegacySyncRoot();
expect(Scheduler).toHaveYielded([
'App',
@@ -331,7 +331,10 @@ describe('ReactSuspensePlaceholder', () => {
jest.advanceTimersByTime(1000);
expect(Scheduler).toHaveYielded(['Promise resolved [Loaded]']);
- expect(Scheduler).toFlushExpired(['Loaded']);
+
+ ReactNoop.flushSync();
+
+ expect(Scheduler).toHaveYielded(['Loaded']);
expect(ReactNoop).toMatchRenderedOutput('LoadedText');
expect(onRender).toHaveBeenCalledTimes(2);
@@ -378,7 +381,7 @@ describe('ReactSuspensePlaceholder', () => {
});
describe('when suspending during update', () => {
- it('properly accounts for base durations when a suspended times out in a legacy tree', () => {
+ it('properly accounts for base durations when a suspended times out in a legacy tree', async () => {
ReactNoop.renderLegacySyncRoot(
,
);
@@ -427,7 +430,10 @@ describe('ReactSuspensePlaceholder', () => {
jest.advanceTimersByTime(1000);
expect(Scheduler).toHaveYielded(['Promise resolved [Loaded]']);
- expect(Scheduler).toFlushExpired(['Loaded']);
+
+ ReactNoop.flushSync();
+
+ expect(Scheduler).toHaveYielded(['Loaded']);
expect(ReactNoop).toMatchRenderedOutput('LoadedNew');
expect(onRender).toHaveBeenCalledTimes(4);
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
index 20971e9f58e91..8e8a512dacf41 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
@@ -1088,9 +1088,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toHaveYielded(['Suspend! [Result]', 'Loading...']);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Result');
+ await ReactNoop.act(async () => {
+ resolveText('Result');
+ });
- expect(Scheduler).toFlushExpired(['Result']);
+ expect(Scheduler).toHaveYielded(['Result']);
expect(ReactNoop.getChildren()).toEqual([span('Result')]);
});
@@ -1156,8 +1158,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('Step: 2');
- expect(Scheduler).toFlushExpired(['Step: 2']);
+ await ReactNoop.act(async () => {
+ resolveText('Step: 2');
+ });
+ expect(Scheduler).toHaveYielded(['Step: 2']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -1227,9 +1231,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('B');
+ await ReactNoop.act(async () => {
+ resolveText('B');
+ });
- expect(Scheduler).toFlushExpired(['B']);
+ expect(Scheduler).toHaveYielded(['B']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -1271,9 +1277,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
]);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Hi');
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
- expect(Scheduler).toFlushExpired([
+ expect(Scheduler).toHaveYielded([
'constructor',
'Hi',
'componentDidMount',
@@ -1316,8 +1324,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading...',
]);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Hi');
- expect(Scheduler).toFlushExpired(['Hi']);
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
+ expect(Scheduler).toHaveYielded(['Hi']);
expect(ReactNoop.getChildren()).toEqual([span('Hi')]);
});
@@ -1360,8 +1370,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
]);
- await resolveText('Hi');
- expect(Scheduler).toFlushExpired(['Hi']);
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
+ expect(Scheduler).toHaveYielded(['Hi']);
});
} else {
// @gate enableCache
@@ -1401,9 +1413,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Child is hidden: true',
]);
- await resolveText('Hi');
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
- expect(Scheduler).toFlushExpired(['Hi']);
+ expect(Scheduler).toHaveYielded(['Hi']);
});
}
@@ -1647,9 +1661,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('B');
+ await ReactNoop.act(async () => {
+ resolveText('B');
+ });
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
'B',
'Destroy Layout Effect [Loading...]',
'Layout Effect [B]',
@@ -1681,9 +1697,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Effect [Loading...]',
]);
- await resolveText('B2');
+ await ReactNoop.act(async () => {
+ resolveText('B2');
+ });
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
'B2',
'Destroy Layout Effect [Loading...]',
'Destroy Layout Effect [B]',
diff --git a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
index db4214bfd0656..cf1db2891e11d 100644
--- a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
@@ -1794,7 +1794,7 @@ describe('useMutableSource', () => {
});
// @gate experimental
- it('should not misidentify mutations after render as side effects', () => {
+ it('should not misidentify mutations after render as side effects', async () => {
const source = createSource('initial');
const mutableSource = createMutableSource(
source,
@@ -1811,15 +1811,16 @@ describe('useMutableSource', () => {
return null;
}
- act(() => {
+ await act(async () => {
ReactNoop.renderLegacySyncRoot(
,
);
- expect(Scheduler).toFlushAndYieldThrough([
- 'MutateDuringRead:initial',
- ]);
+ });
+ expect(Scheduler).toHaveYielded(['MutateDuringRead:initial']);
+
+ await act(async () => {
source.value = 'updated';
});
expect(Scheduler).toHaveYielded(['MutateDuringRead:updated']);
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 3d0362f4b3fcd..56ad7fa587afd 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -151,4 +151,6 @@ export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
+
export const enableNativeEventPriorityInference = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index f97f4f428c181..790887b7e7cee 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -59,6 +59,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 9d160790b3fec..8b54ff76d2f6e 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 52990e5ec7b71..78f1ed1b9a098 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
index 3c739b7bccb39..c25b8e6e04029 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index fb2211763c03d..ff5c7c43d0864 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js
index 34e6d5315742f..696de3ce78dd7 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js
index 4f0c56733eafd..d33d0683c15a7 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js
@@ -58,6 +58,7 @@ export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableNonInterruptingNormalPri = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
index b6e1d4260cc4a..b43f53fbfae19 100644
--- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
@@ -57,4 +57,5 @@ export const enableProfilerNestedUpdateScheduledHook = __VARIANT__;
export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
export const enableNonInterruptingNormalPri = __VARIANT__;
export const enableDiscreteEventMicroTasks = __VARIANT__;
+export const enableSyncMicroTasks = __VARIANT__;
export const enableNativeEventPriorityInference = __VARIANT__;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 924fd6ea9e5bd..21cc7979df98c 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -33,6 +33,7 @@ export const {
disableSchedulerTimeoutInWorkLoop,
enableNonInterruptingNormalPri,
enableDiscreteEventMicroTasks,
+ enableSyncMicroTasks,
enableNativeEventPriorityInference,
} = dynamicFeatureFlags;