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 377fa61e507d7..795eda90c83cc 100644 --- a/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js +++ b/packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js @@ -477,8 +477,8 @@ describe('SimpleEventPlugin', function() { // 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? + ]); + expect(Scheduler).toFlushAndYield([ 'High-pri count: 8, Low-pri count: 8', ]); } else { diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 6935bb4b1f18d..918261a2e3562 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -1028,6 +1028,20 @@ function performSyncWorkOnRoot(root) { exitStatus = renderRootSync(root, lanes); } else { lanes = getNextLanes(root, NoLanes); + // Because we don't cancel synchronous tasks, sometimes more than one + // synchronous task ends up being scheduled. This is an artifact of the fact + // that we have two different lanes that schedule sync tasks: discrete and + // sync. If we had only one, then (I believe) this extra check wouldn't be + // necessary, because there's nothing higher priority than sync that would + // cause us to cancel it. + // TODO: Merge InputDiscreteLanePriority with SyncLanePriority, then delete + // this bailout. + if (supportsMicrotasks) { + const nextLanesPriority = returnNextLanesPriority(); + if (nextLanesPriority < InputDiscreteLanePriority) { + return null; + } + } exitStatus = renderRootSync(root, lanes); } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 2b57becf8bd79..12ef384a47527 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -1028,6 +1028,20 @@ function performSyncWorkOnRoot(root) { exitStatus = renderRootSync(root, lanes); } else { lanes = getNextLanes(root, NoLanes); + // Because we don't cancel synchronous tasks, sometimes more than one + // synchronous task ends up being scheduled. This is an artifact of the fact + // that we have two different lanes that schedule sync tasks: discrete and + // sync. If we had only one, then (I believe) this extra check wouldn't be + // necessary, because there's nothing higher priority than sync that would + // cause us to cancel it. + // TODO: Merge InputDiscreteLanePriority with SyncLanePriority, then delete + // this bailout. + if (supportsMicrotasks) { + const nextLanesPriority = returnNextLanesPriority(); + if (nextLanesPriority < InputDiscreteLanePriority) { + return null; + } + } exitStatus = renderRootSync(root, lanes); }