diff --git a/packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js b/packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js index 2a806b2888c18..45828e2735ed7 100644 --- a/packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js +++ b/packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js @@ -730,8 +730,15 @@ describe('ChangeEventPlugin', () => { // Flush callbacks. // Now the click update has flushed. - expect(Scheduler).toFlushAndYield(['render: ']); - expect(input.value).toBe(''); + if (gate(flags => flags.enableDiscreteEventMicroTasks)) { + // Flush microtask queue. + await null; + expect(Scheduler).toHaveYielded(['render: ']); + expect(input.value).toBe(''); + } else { + expect(Scheduler).toFlushAndYield(['render: ']); + expect(input.value).toBe(''); + } }); // @gate experimental diff --git a/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js b/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js index 0579e9571cbc2..377fa61e507d7 100644 --- a/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js +++ b/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js @@ -470,11 +470,24 @@ describe('SimpleEventPlugin', function() { 'High-pri count: 7, Low-pri count: 0', ]); - // At the end, both counters should equal the total number of clicks - expect(Scheduler).toFlushAndYield([ - 'High-pri count: 8, Low-pri count: 0', - 'High-pri count: 8, Low-pri count: 8', - ]); + if (gate(flags => flags.enableDiscreteEventMicroTasks)) { + // Flush the microtask queue + await null; + + // At the end, both counters should equal the total number of clicks + expect(Scheduler).toHaveYielded([ + 'High-pri count: 8, Low-pri count: 0', + + // TODO: with cancellation, this required another flush? + 'High-pri count: 8, Low-pri count: 8', + ]); + } else { + // At the end, both counters should equal the total number of clicks + expect(Scheduler).toFlushAndYield([ + 'High-pri count: 8, Low-pri count: 0', + 'High-pri count: 8, Low-pri count: 8', + ]); + } expect(button.textContent).toEqual('High-pri count: 8, Low-pri count: 8'); }); }); diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index dff64f9cae95d..ef773c8d16165 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -91,6 +91,7 @@ import { warnsIfNotActing, afterActiveInstanceBlur, clearContainer, + queueMicrotask, } from './ReactFiberHostConfig'; import { @@ -214,6 +215,7 @@ import { syncNestedUpdateFlag, } from './ReactProfilerTimer.new'; +import {enableDiscreteEventMicroTasks} from 'shared/ReactFeatureFlags'; // DEV stuff import getComponentName from 'shared/getComponentName'; import ReactStrictModeWarnings from './ReactStrictModeWarnings.new'; @@ -726,6 +728,13 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { ImmediateSchedulerPriority, performSyncWorkOnRoot.bind(null, root), ); + } else if ( + enableDiscreteEventMicroTasks && + queueMicrotask != null && + newCallbackPriority === InputDiscreteLanePriority + ) { + queueMicrotask(performSyncWorkOnRoot.bind(null, root)); + newCallbackNode = null; } else { const schedulerPriorityLevel = lanePriorityToSchedulerPriority( newCallbackPriority, diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index c3ffb65e96ff2..06980510837d1 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -143,3 +143,5 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; + +export const enableDiscreteEventMicroTasks = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 23c926c65a3fb..0f5f1d816a343 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -57,6 +57,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 3ed2d7701c93f..7a1ad95bdc13a 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index c6ffacb27bab2..ba805120f4248 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 84ea8902f60c2..7ea4401fdb966 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index eb1630fc49bd7..7d7a4d9f0ee1c 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 87133385439f3..c4a95889fc995 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index 671f44be02952..aea075b3c2688 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -56,6 +56,7 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; export const disableSchedulerTimeoutInWorkLoop = false; +export const enableDiscreteEventMicroTasks = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index cf0ca5ae54393..f969cb743b250 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -54,3 +54,4 @@ export const enableUseRefAccessWarning = __VARIANT__; export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; +export const enableDiscreteEventMicroTasks = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 8b2bda551339e..78b05ab153ad7 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -30,6 +30,7 @@ export const { enableUseRefAccessWarning, disableNativeComponentFrames, disableSchedulerTimeoutInWorkLoop, + enableDiscreteEventMicroTasks, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.