From 03ede83d2ea1878e5cb82c3c17844621989caf66 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 25 Mar 2021 11:21:41 -0500 Subject: [PATCH] Use EventPriority to track update priority (#21082) Instead of LanePriority. Internally, EventPriority is just a lane, so this skips an extra conversion. Since EventPriority is a "public" (to the host config) type, I was also able to remove some deep imports of the Lane module. This gets us most of the way to deleting the LanePriority entirely. --- ...DOMServerPartialHydration-test.internal.js | 10 +- ...MServerSelectiveHydration-test.internal.js | 9 +- packages/react-dom/src/client/ReactDOM.js | 8 +- .../src/events/ReactDOMEventListener.js | 29 +----- .../src/events/ReactDOMEventReplaying.js | 28 ++++-- .../src/ReactEventPriorities.js | 61 +++++++++--- .../src/ReactEventPriorities.new.js | 70 +++++++++++++- .../src/ReactEventPriorities.old.js | 70 +++++++++++++- .../src/ReactFiberCommitWork.new.js | 80 +++------------- .../src/ReactFiberCommitWork.old.js | 80 +++------------- .../src/ReactFiberDevToolsHook.new.js | 41 ++++++-- .../src/ReactFiberDevToolsHook.old.js | 41 ++++++-- .../src/ReactFiberHooks.new.js | 22 +++-- .../src/ReactFiberHooks.old.js | 22 +++-- .../src/ReactFiberLane.new.js | 45 +-------- .../src/ReactFiberLane.old.js | 45 +-------- .../src/ReactFiberReconciler.js | 10 +- .../src/ReactFiberReconciler.new.js | 20 ++-- .../src/ReactFiberReconciler.old.js | 20 ++-- .../src/ReactFiberWorkLoop.new.js | 93 ++++++++++--------- .../src/ReactFiberWorkLoop.old.js | 93 ++++++++++--------- .../src/SchedulerWithReactIntegration.new.js | 16 ++-- .../src/SchedulerWithReactIntegration.old.js | 16 ++-- .../__tests__/ReactIncrementalUpdates-test.js | 16 ++-- .../ReactDOMTracing-test.internal.js | 18 ++-- 25 files changed, 484 insertions(+), 479 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index 5f127d37fcdd..d37845c01b38 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -17,11 +17,7 @@ let ReactFeatureFlags; let Suspense; let SuspenseList; let act; - -// Copied from ReactFiberLanes. Don't do this! -// This is hard coded directly to avoid needing to import, and -// we'll remove this as we replace runWithPriority with React APIs. -export const IdleLanePriority = 2; +let IdleEventPriority; function dispatchMouseEvent(to, from) { if (!to) { @@ -89,6 +85,8 @@ describe('ReactDOMServerPartialHydration', () => { Scheduler = require('scheduler'); Suspense = React.Suspense; SuspenseList = React.SuspenseList; + + IdleEventPriority = require('react-reconciler/constants').IdleEventPriority; }); // Note: This is based on a similar component we use in www. We can delete @@ -628,7 +626,7 @@ describe('ReactDOMServerPartialHydration', () => { expect(span.textContent).toBe('Hello'); // Schedule an update at idle priority - ReactDOM.unstable_runWithPriority(IdleLanePriority, () => { + ReactDOM.unstable_runWithPriority(IdleEventPriority, () => { root.render(); }); diff --git a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js index cadc00e886fa..4e3192fdce76 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js @@ -19,10 +19,7 @@ let Scheduler; let Suspense; let act; -// Copied from ReactFiberLanes. Don't do this! -// This is hard coded directly to avoid needing to import, and -// we'll remove this as we replace runWithPriority with React APIs. -export const IdleLanePriority = 2; +let IdleEventPriority; function dispatchMouseHoverEvent(to, from) { if (!to) { @@ -101,7 +98,7 @@ function dispatchClickEvent(target) { // and there's no native DOM event that maps to idle priority, so this is a // temporary workaround. Need something like ReactDOM.unstable_IdleUpdates. function TODO_scheduleIdleDOMSchedulerTask(fn) { - ReactDOM.unstable_runWithPriority(IdleLanePriority, () => { + ReactDOM.unstable_runWithPriority(IdleEventPriority, () => { const prevEvent = window.event; window.event = {type: 'message'}; try { @@ -125,6 +122,8 @@ describe('ReactDOMServerSelectiveHydration', () => { act = ReactTestUtils.unstable_concurrentAct; Scheduler = require('scheduler'); Suspense = React.Suspense; + + IdleEventPriority = require('react-reconciler/constants').IdleEventPriority; }); // @gate experimental diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 7cff285a938d..aeeb5b307063 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -35,9 +35,11 @@ import { attemptDiscreteHydration, attemptContinuousHydration, attemptHydrationAtCurrentPriority, - runWithPriority, - getCurrentUpdateLanePriority, } from 'react-reconciler/src/ReactFiberReconciler'; +import { + runWithPriority, + getCurrentUpdatePriority, +} from 'react-reconciler/src/ReactEventPriorities'; import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal'; import {canUseDOM} from 'shared/ExecutionEnvironment'; import ReactVersion from 'shared/ReactVersion'; @@ -74,7 +76,7 @@ setAttemptSynchronousHydration(attemptSynchronousHydration); setAttemptDiscreteHydration(attemptDiscreteHydration); setAttemptContinuousHydration(attemptContinuousHydration); setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority); -setGetCurrentUpdatePriority(getCurrentUpdateLanePriority); +setGetCurrentUpdatePriority(getCurrentUpdatePriority); setAttemptHydrationAtPriority(runWithPriority); let didWarnAboutUnstableCreatePortal = false; diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index d1d8646d6087..8197a2da242a 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -44,16 +44,6 @@ import { discreteUpdates, } from './ReactDOMUpdateBatching'; -import { - InputContinuousLanePriority as InputContinuousLanePriority_old, - getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_old, - setCurrentUpdateLanePriority as setCurrentUpdateLanePriority_old, -} from 'react-reconciler/src/ReactFiberLane.old'; -import { - InputContinuousLanePriority as InputContinuousLanePriority_new, - getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_new, - setCurrentUpdateLanePriority as setCurrentUpdateLanePriority_new, -} from 'react-reconciler/src/ReactFiberLane.new'; import {getCurrentPriorityLevel as getCurrentPriorityLevel_old} from 'react-reconciler/src/SchedulerWithReactIntegration.old'; import { getCurrentPriorityLevel as getCurrentPriorityLevel_new, @@ -68,19 +58,10 @@ import { ContinuousEventPriority, DefaultEventPriority, IdleEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, } from 'react-reconciler/src/ReactEventPriorities'; -// TODO: These should use the opaque EventPriority type instead of LanePriority. -// Then internally we can use a Lane. -const InputContinuousLanePriority = enableNewReconciler - ? InputContinuousLanePriority_new - : InputContinuousLanePriority_old; -const getCurrentUpdateLanePriority = enableNewReconciler - ? getCurrentUpdateLanePriority_new - : getCurrentUpdateLanePriority_old; -const setCurrentUpdateLanePriority = enableNewReconciler - ? setCurrentUpdateLanePriority_new - : setCurrentUpdateLanePriority_old; const getCurrentPriorityLevel = enableNewReconciler ? getCurrentPriorityLevel_new : getCurrentPriorityLevel_old; @@ -167,12 +148,12 @@ function dispatchContinuousEvent( container, nativeEvent, ) { - const previousPriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(InputContinuousLanePriority); + setCurrentUpdatePriority(ContinuousEventPriority); dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent); } finally { - setCurrentUpdateLanePriority(previousPriority); + setCurrentUpdatePriority(previousPriority); } } diff --git a/packages/react-dom/src/events/ReactDOMEventReplaying.js b/packages/react-dom/src/events/ReactDOMEventReplaying.js index 3a084605e575..0587899fd8bd 100644 --- a/packages/react-dom/src/events/ReactDOMEventReplaying.js +++ b/packages/react-dom/src/events/ReactDOMEventReplaying.js @@ -12,7 +12,7 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig'; import type {DOMEventName} from '../events/DOMEventNames'; import type {EventSystemFlags} from './EventSystemFlags'; import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes'; -import type {LanePriority} from 'react-reconciler/src/ReactFiberLane.old'; +import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities'; import {enableSelectiveHydration} from 'shared/ReactFeatureFlags'; import { @@ -30,6 +30,7 @@ import { getClosestInstanceFromNode, } from '../client/ReactDOMComponentTree'; import {HostRoot, SuspenseComponent} from 'react-reconciler/src/ReactWorkTags'; +import {isHigherEventPriority} from 'react-reconciler/src/ReactEventPriorities'; let attemptSynchronousHydration: (fiber: Object) => void; @@ -57,16 +58,16 @@ export function setAttemptHydrationAtCurrentPriority( attemptHydrationAtCurrentPriority = fn; } -let getCurrentUpdatePriority: () => LanePriority; +let getCurrentUpdatePriority: () => EventPriority; -export function setGetCurrentUpdatePriority(fn: () => LanePriority) { +export function setGetCurrentUpdatePriority(fn: () => EventPriority) { getCurrentUpdatePriority = fn; } -let attemptHydrationAtPriority: (priority: LanePriority, fn: () => T) => T; +let attemptHydrationAtPriority: (priority: EventPriority, fn: () => T) => T; export function setAttemptHydrationAtPriority( - fn: (priority: LanePriority, fn: () => T) => T, + fn: (priority: EventPriority, fn: () => T) => T, ) { attemptHydrationAtPriority = fn; } @@ -109,7 +110,7 @@ const queuedPointerCaptures: Map = new Map(); type QueuedHydrationTarget = {| blockedOn: null | Container | SuspenseInstance, target: Node, - lanePriority: LanePriority, + priority: EventPriority, |}; const queuedExplicitHydrationTargets: Array = []; @@ -390,7 +391,7 @@ function attemptExplicitHydrationTarget( // We're blocked on hydrating this boundary. // Increase its priority. queuedTarget.blockedOn = instance; - attemptHydrationAtPriority(queuedTarget.lanePriority, () => { + attemptHydrationAtPriority(queuedTarget.priority, () => { attemptHydrationAtCurrentPriority(nearestMounted); }); @@ -412,16 +413,23 @@ function attemptExplicitHydrationTarget( export function queueExplicitHydrationTarget(target: Node): void { if (enableSelectiveHydration) { - const updateLanePriority = getCurrentUpdatePriority(); + // TODO: This will read the priority if it's dispatched by the React + // event system but not native events. Should read window.event.type, like + // we do for updates (getCurrentEventPriority). + const updatePriority = getCurrentUpdatePriority(); const queuedTarget: QueuedHydrationTarget = { blockedOn: null, target: target, - lanePriority: updateLanePriority, + priority: updatePriority, }; let i = 0; for (; i < queuedExplicitHydrationTargets.length; i++) { + // Stop once we hit the first target with lower priority than if ( - updateLanePriority <= queuedExplicitHydrationTargets[i].lanePriority + !isHigherEventPriority( + updatePriority, + queuedExplicitHydrationTargets[i].priority, + ) ) { break; } diff --git a/packages/react-reconciler/src/ReactEventPriorities.js b/packages/react-reconciler/src/ReactEventPriorities.js index 76385f612afe..46223aa70df5 100644 --- a/packages/react-reconciler/src/ReactEventPriorities.js +++ b/packages/react-reconciler/src/ReactEventPriorities.js @@ -14,6 +14,10 @@ import { ContinuousEventPriority as ContinuousEventPriority_old, DefaultEventPriority as DefaultEventPriority_old, IdleEventPriority as IdleEventPriority_old, + getCurrentUpdatePriority as getCurrentUpdatePriority_old, + setCurrentUpdatePriority as setCurrentUpdatePriority_old, + runWithPriority as runWithPriority_old, + isHigherEventPriority as isHigherEventPriority_old, } from './ReactEventPriorities.old'; import { @@ -21,17 +25,50 @@ import { ContinuousEventPriority as ContinuousEventPriority_new, DefaultEventPriority as DefaultEventPriority_new, IdleEventPriority as IdleEventPriority_new, + getCurrentUpdatePriority as getCurrentUpdatePriority_new, + setCurrentUpdatePriority as setCurrentUpdatePriority_new, + runWithPriority as runWithPriority_new, + isHigherEventPriority as isHigherEventPriority_new, } from './ReactEventPriorities.new'; -export const DiscreteEventPriority = enableNewReconciler - ? DiscreteEventPriority_new - : DiscreteEventPriority_old; -export const ContinuousEventPriority = enableNewReconciler - ? ContinuousEventPriority_new - : ContinuousEventPriority_old; -export const DefaultEventPriority = enableNewReconciler - ? DefaultEventPriority_new - : DefaultEventPriority_old; -export const IdleEventPriority = enableNewReconciler - ? IdleEventPriority_new - : IdleEventPriority_old; +export opaque type EventPriority = number; + +export const DiscreteEventPriority: EventPriority = enableNewReconciler + ? (DiscreteEventPriority_new: any) + : (DiscreteEventPriority_old: any); +export const ContinuousEventPriority: EventPriority = enableNewReconciler + ? (ContinuousEventPriority_new: any) + : (ContinuousEventPriority_old: any); +export const DefaultEventPriority: EventPriority = enableNewReconciler + ? (DefaultEventPriority_new: any) + : (DefaultEventPriority_old: any); +export const IdleEventPriority: EventPriority = enableNewReconciler + ? (IdleEventPriority_new: any) + : (IdleEventPriority_old: any); + +export function runWithPriority(priority: EventPriority, fn: () => T): T { + return enableNewReconciler + ? runWithPriority_new((priority: any), fn) + : runWithPriority_old((priority: any), fn); +} + +export function getCurrentUpdatePriority(): EventPriority { + return enableNewReconciler + ? (getCurrentUpdatePriority_new(): any) + : (getCurrentUpdatePriority_old(): any); +} + +export function setCurrentUpdatePriority(priority: EventPriority) { + return enableNewReconciler + ? setCurrentUpdatePriority_new((priority: any)) + : setCurrentUpdatePriority_old((priority: any)); +} + +export function isHigherEventPriority( + a: EventPriority, + b: EventPriority, +): boolean { + return enableNewReconciler + ? isHigherEventPriority_new((a: any), (b: any)) + : isHigherEventPriority_old((a: any), (b: any)); +} diff --git a/packages/react-reconciler/src/ReactEventPriorities.new.js b/packages/react-reconciler/src/ReactEventPriorities.new.js index d8eb817db1c5..2c1b9c249fa9 100644 --- a/packages/react-reconciler/src/ReactEventPriorities.new.js +++ b/packages/react-reconciler/src/ReactEventPriorities.new.js @@ -7,9 +7,69 @@ * @flow */ -export { - SyncLane as DiscreteEventPriority, - InputContinuousLane as ContinuousEventPriority, - DefaultLane as DefaultEventPriority, - IdleLane as IdleEventPriority, +import type {Lane, Lanes} from './ReactFiberLane.new'; + +import { + NoLane, + SyncLane, + InputContinuousLane, + DefaultLane, + IdleLane, + getHighestPriorityLane, + includesNonIdleWork, } from './ReactFiberLane.new'; + +export opaque type EventPriority = Lane; + +export const DiscreteEventPriority: EventPriority = SyncLane; +export const ContinuousEventPriority: EventPriority = InputContinuousLane; +export const DefaultEventPriority: EventPriority = DefaultLane; +export const IdleEventPriority: EventPriority = IdleLane; + +let currentUpdatePriority: EventPriority = NoLane; + +export function getCurrentUpdatePriority(): EventPriority { + return currentUpdatePriority; +} + +export function setCurrentUpdatePriority(newPriority: EventPriority) { + currentUpdatePriority = newPriority; +} + +export function runWithPriority(priority: EventPriority, fn: () => T): T { + const previousPriority = currentUpdatePriority; + try { + currentUpdatePriority = priority; + return fn(); + } finally { + currentUpdatePriority = previousPriority; + } +} + +export function higherEventPriority( + a: EventPriority, + b: EventPriority, +): EventPriority { + return a !== 0 && a < b ? a : b; +} + +export function isHigherEventPriority( + a: EventPriority, + b: EventPriority, +): boolean { + return a !== 0 && a < b; +} + +export function lanesToEventPriority(lanes: Lanes): EventPriority { + const lane = getHighestPriorityLane(lanes); + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; + } + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; + } + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; + } + return IdleEventPriority; +} diff --git a/packages/react-reconciler/src/ReactEventPriorities.old.js b/packages/react-reconciler/src/ReactEventPriorities.old.js index 8db438ed25e4..7e1b0acb7a9a 100644 --- a/packages/react-reconciler/src/ReactEventPriorities.old.js +++ b/packages/react-reconciler/src/ReactEventPriorities.old.js @@ -7,9 +7,69 @@ * @flow */ -export { - SyncLane as DiscreteEventPriority, - InputContinuousLane as ContinuousEventPriority, - DefaultLane as DefaultEventPriority, - IdleLane as IdleEventPriority, +import type {Lane, Lanes} from './ReactFiberLane.old'; + +import { + NoLane, + SyncLane, + InputContinuousLane, + DefaultLane, + IdleLane, + getHighestPriorityLane, + includesNonIdleWork, } from './ReactFiberLane.old'; + +export opaque type EventPriority = Lane; + +export const DiscreteEventPriority: EventPriority = SyncLane; +export const ContinuousEventPriority: EventPriority = InputContinuousLane; +export const DefaultEventPriority: EventPriority = DefaultLane; +export const IdleEventPriority: EventPriority = IdleLane; + +let currentUpdatePriority: EventPriority = NoLane; + +export function getCurrentUpdatePriority(): EventPriority { + return currentUpdatePriority; +} + +export function setCurrentUpdatePriority(newPriority: EventPriority) { + currentUpdatePriority = newPriority; +} + +export function runWithPriority(priority: EventPriority, fn: () => T): T { + const previousPriority = currentUpdatePriority; + try { + currentUpdatePriority = priority; + return fn(); + } finally { + currentUpdatePriority = previousPriority; + } +} + +export function higherEventPriority( + a: EventPriority, + b: EventPriority, +): EventPriority { + return a !== 0 && a < b ? a : b; +} + +export function isHigherEventPriority( + a: EventPriority, + b: EventPriority, +): boolean { + return a !== 0 && a < b; +} + +export function lanesToEventPriority(lanes: Lanes): EventPriority { + const lane = getHighestPriorityLane(lanes); + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; + } + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; + } + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; + } + return IdleEventPriority; +} diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index 3bf394007422..9bcaa5a4d753 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -17,7 +17,7 @@ import type { } from './ReactFiberHostConfig'; import type {Fiber} from './ReactInternalTypes'; import type {FiberRoot} from './ReactInternalTypes'; -import type {LanePriority, Lanes} from './ReactFiberLane.new'; +import type {Lanes} from './ReactFiberLane.new'; import type {SuspenseState} from './ReactFiberSuspenseComponent.new'; import type {UpdateQueue} from './ReactUpdateQueue.new'; import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new'; @@ -1067,7 +1067,6 @@ function commitUnmount( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { onCommitUnmount(current); @@ -1127,12 +1126,7 @@ function commitUnmount( // We are also not using this parent because // the portal will get pushed immediately. if (supportsMutation) { - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } else if (supportsPersistence) { emptyPortalContainer(current); } @@ -1163,7 +1157,6 @@ function commitNestedUnmounts( finishedRoot: FiberRoot, root: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { // While we're inside a removed host node we don't want to call // removeChild on the inner nodes because they're removed by the top @@ -1172,12 +1165,7 @@ function commitNestedUnmounts( // we do an inner loop while we're still inside the host node. let node: Fiber = root; while (true) { - commitUnmount( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. // Skip portals because commitUnmount() currently visits them recursively. if ( @@ -1532,7 +1520,6 @@ function unmountHostComponents( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { // We only have the top Fiber that was deleted but we need to recurse down its // children to find all the terminal nodes. @@ -1576,12 +1563,7 @@ function unmountHostComponents( } if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the // node from the tree. if (currentParentIsContainer) { @@ -1634,12 +1616,7 @@ function unmountHostComponents( continue; } } else { - commitUnmount( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. if (node.child !== null) { node.child.return = node; @@ -1670,25 +1647,14 @@ function commitDeletion( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { if (supportsMutation) { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } else { // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); } detachFiberMutation(current); @@ -2009,19 +1975,12 @@ function commitResetTextContent(current: Fiber) { resetTextContent(current.stateNode); } -export function commitMutationEffects( - root: FiberRoot, - renderPriorityLevel: LanePriority, - firstChild: Fiber, -) { +export function commitMutationEffects(root: FiberRoot, firstChild: Fiber) { nextEffect = firstChild; - commitMutationEffects_begin(root, renderPriorityLevel); + commitMutationEffects_begin(root); } -function commitMutationEffects_begin( - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffects_begin(root: FiberRoot) { while (nextEffect !== null) { const fiber = nextEffect; @@ -2038,7 +1997,6 @@ function commitMutationEffects_begin( root, childToDelete, fiber, - renderPriorityLevel, ); if (hasCaughtError()) { const error = clearCaughtError(); @@ -2046,7 +2004,7 @@ function commitMutationEffects_begin( } } else { try { - commitDeletion(root, childToDelete, fiber, renderPriorityLevel); + commitDeletion(root, childToDelete, fiber); } catch (error) { captureCommitPhaseError(childToDelete, fiber, error); } @@ -2059,15 +2017,12 @@ function commitMutationEffects_begin( ensureCorrectReturnPointer(child, fiber); nextEffect = child; } else { - commitMutationEffects_complete(root, renderPriorityLevel); + commitMutationEffects_complete(root); } } } -function commitMutationEffects_complete( - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffects_complete(root: FiberRoot) { while (nextEffect !== null) { const fiber = nextEffect; if (__DEV__) { @@ -2078,7 +2033,6 @@ function commitMutationEffects_complete( null, fiber, root, - renderPriorityLevel, ); if (hasCaughtError()) { const error = clearCaughtError(); @@ -2087,7 +2041,7 @@ function commitMutationEffects_complete( resetCurrentDebugFiberInDEV(); } else { try { - commitMutationEffectsOnFiber(fiber, root, renderPriorityLevel); + commitMutationEffectsOnFiber(fiber, root); } catch (error) { captureCommitPhaseError(fiber, fiber.return, error); } @@ -2104,11 +2058,7 @@ function commitMutationEffects_complete( } } -function commitMutationEffectsOnFiber( - finishedWork: Fiber, - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffectsOnFiber(finishedWork: Fiber, root: FiberRoot) { const flags = finishedWork.flags; if (flags & ContentReset) { diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.old.js b/packages/react-reconciler/src/ReactFiberCommitWork.old.js index 7f4da55e76e2..6b184f30d3d9 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.old.js @@ -17,7 +17,7 @@ import type { } from './ReactFiberHostConfig'; import type {Fiber} from './ReactInternalTypes'; import type {FiberRoot} from './ReactInternalTypes'; -import type {LanePriority, Lanes} from './ReactFiberLane.old'; +import type {Lanes} from './ReactFiberLane.old'; import type {SuspenseState} from './ReactFiberSuspenseComponent.old'; import type {UpdateQueue} from './ReactUpdateQueue.old'; import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.old'; @@ -1067,7 +1067,6 @@ function commitUnmount( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { onCommitUnmount(current); @@ -1127,12 +1126,7 @@ function commitUnmount( // We are also not using this parent because // the portal will get pushed immediately. if (supportsMutation) { - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } else if (supportsPersistence) { emptyPortalContainer(current); } @@ -1163,7 +1157,6 @@ function commitNestedUnmounts( finishedRoot: FiberRoot, root: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { // While we're inside a removed host node we don't want to call // removeChild on the inner nodes because they're removed by the top @@ -1172,12 +1165,7 @@ function commitNestedUnmounts( // we do an inner loop while we're still inside the host node. let node: Fiber = root; while (true) { - commitUnmount( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. // Skip portals because commitUnmount() currently visits them recursively. if ( @@ -1532,7 +1520,6 @@ function unmountHostComponents( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { // We only have the top Fiber that was deleted but we need to recurse down its // children to find all the terminal nodes. @@ -1576,12 +1563,7 @@ function unmountHostComponents( } if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the // node from the tree. if (currentParentIsContainer) { @@ -1634,12 +1616,7 @@ function unmountHostComponents( continue; } } else { - commitUnmount( - finishedRoot, - node, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. if (node.child !== null) { node.child.return = node; @@ -1670,25 +1647,14 @@ function commitDeletion( finishedRoot: FiberRoot, current: Fiber, nearestMountedAncestor: Fiber, - renderPriorityLevel: LanePriority, ): void { if (supportsMutation) { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } else { // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel, - ); + commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); } detachFiberMutation(current); @@ -2009,19 +1975,12 @@ function commitResetTextContent(current: Fiber) { resetTextContent(current.stateNode); } -export function commitMutationEffects( - root: FiberRoot, - renderPriorityLevel: LanePriority, - firstChild: Fiber, -) { +export function commitMutationEffects(root: FiberRoot, firstChild: Fiber) { nextEffect = firstChild; - commitMutationEffects_begin(root, renderPriorityLevel); + commitMutationEffects_begin(root); } -function commitMutationEffects_begin( - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffects_begin(root: FiberRoot) { while (nextEffect !== null) { const fiber = nextEffect; @@ -2038,7 +1997,6 @@ function commitMutationEffects_begin( root, childToDelete, fiber, - renderPriorityLevel, ); if (hasCaughtError()) { const error = clearCaughtError(); @@ -2046,7 +2004,7 @@ function commitMutationEffects_begin( } } else { try { - commitDeletion(root, childToDelete, fiber, renderPriorityLevel); + commitDeletion(root, childToDelete, fiber); } catch (error) { captureCommitPhaseError(childToDelete, fiber, error); } @@ -2059,15 +2017,12 @@ function commitMutationEffects_begin( ensureCorrectReturnPointer(child, fiber); nextEffect = child; } else { - commitMutationEffects_complete(root, renderPriorityLevel); + commitMutationEffects_complete(root); } } } -function commitMutationEffects_complete( - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffects_complete(root: FiberRoot) { while (nextEffect !== null) { const fiber = nextEffect; if (__DEV__) { @@ -2078,7 +2033,6 @@ function commitMutationEffects_complete( null, fiber, root, - renderPriorityLevel, ); if (hasCaughtError()) { const error = clearCaughtError(); @@ -2087,7 +2041,7 @@ function commitMutationEffects_complete( resetCurrentDebugFiberInDEV(); } else { try { - commitMutationEffectsOnFiber(fiber, root, renderPriorityLevel); + commitMutationEffectsOnFiber(fiber, root); } catch (error) { captureCommitPhaseError(fiber, fiber.return, error); } @@ -2104,11 +2058,7 @@ function commitMutationEffects_complete( } } -function commitMutationEffectsOnFiber( - finishedWork: Fiber, - root: FiberRoot, - renderPriorityLevel: LanePriority, -) { +function commitMutationEffectsOnFiber(finishedWork: Fiber, root: FiberRoot) { const flags = finishedWork.flags; if (flags & ContentReset) { diff --git a/packages/react-reconciler/src/ReactFiberDevToolsHook.new.js b/packages/react-reconciler/src/ReactFiberDevToolsHook.new.js index 6ac250743ad9..afcbad36f155 100644 --- a/packages/react-reconciler/src/ReactFiberDevToolsHook.new.js +++ b/packages/react-reconciler/src/ReactFiberDevToolsHook.new.js @@ -11,14 +11,21 @@ import {enableProfilerTimer} from 'shared/ReactFeatureFlags'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {ReactNodeList} from 'shared/ReactTypes'; -import type {LanePriority} from './ReactFiberLane.new'; +import type {EventPriority} from './ReactEventPriorities.new'; import {DidCapture} from './ReactFiberFlags'; import { - lanePriorityToSchedulerPriority, - NoLanePriority, -} from './ReactFiberLane.new'; -import {NormalPriority} from './SchedulerWithReactIntegration.new'; + DiscreteEventPriority, + ContinuousEventPriority, + DefaultEventPriority, + IdleEventPriority, +} from './ReactEventPriorities.new'; +import { + ImmediatePriority as ImmediateSchedulerPriority, + UserBlockingPriority as UserBlockingSchedulerPriority, + NormalPriority as NormalSchedulerPriority, + IdlePriority as IdleSchedulerPriority, +} from './SchedulerWithReactIntegration.new'; declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void; @@ -84,15 +91,29 @@ export function onScheduleRoot(root: FiberRoot, children: ReactNodeList) { } } -export function onCommitRoot(root: FiberRoot, priorityLevel: LanePriority) { +export function onCommitRoot(root: FiberRoot, eventPriority: EventPriority) { if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') { try { const didError = (root.current.flags & DidCapture) === DidCapture; if (enableProfilerTimer) { - const schedulerPriority = - priorityLevel === NoLanePriority - ? NormalPriority - : lanePriorityToSchedulerPriority(priorityLevel); + let schedulerPriority; + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediateSchedulerPriority; + break; + case ContinuousEventPriority: + schedulerPriority = UserBlockingSchedulerPriority; + break; + case DefaultEventPriority: + schedulerPriority = NormalSchedulerPriority; + break; + case IdleEventPriority: + schedulerPriority = IdleSchedulerPriority; + break; + default: + schedulerPriority = NormalSchedulerPriority; + break; + } injectedHook.onCommitFiberRoot( rendererID, root, diff --git a/packages/react-reconciler/src/ReactFiberDevToolsHook.old.js b/packages/react-reconciler/src/ReactFiberDevToolsHook.old.js index 04aa1c09eb43..39cd1f02cf99 100644 --- a/packages/react-reconciler/src/ReactFiberDevToolsHook.old.js +++ b/packages/react-reconciler/src/ReactFiberDevToolsHook.old.js @@ -11,14 +11,21 @@ import {enableProfilerTimer} from 'shared/ReactFeatureFlags'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {ReactNodeList} from 'shared/ReactTypes'; -import type {LanePriority} from './ReactFiberLane.old'; +import type {EventPriority} from './ReactEventPriorities.old'; import {DidCapture} from './ReactFiberFlags'; import { - lanePriorityToSchedulerPriority, - NoLanePriority, -} from './ReactFiberLane.old'; -import {NormalPriority} from './SchedulerWithReactIntegration.old'; + DiscreteEventPriority, + ContinuousEventPriority, + DefaultEventPriority, + IdleEventPriority, +} from './ReactEventPriorities.old'; +import { + ImmediatePriority as ImmediateSchedulerPriority, + UserBlockingPriority as UserBlockingSchedulerPriority, + NormalPriority as NormalSchedulerPriority, + IdlePriority as IdleSchedulerPriority, +} from './SchedulerWithReactIntegration.old'; declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void; @@ -84,15 +91,29 @@ export function onScheduleRoot(root: FiberRoot, children: ReactNodeList) { } } -export function onCommitRoot(root: FiberRoot, priorityLevel: LanePriority) { +export function onCommitRoot(root: FiberRoot, eventPriority: EventPriority) { if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') { try { const didError = (root.current.flags & DidCapture) === DidCapture; if (enableProfilerTimer) { - const schedulerPriority = - priorityLevel === NoLanePriority - ? NormalPriority - : lanePriorityToSchedulerPriority(priorityLevel); + let schedulerPriority; + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediateSchedulerPriority; + break; + case ContinuousEventPriority: + schedulerPriority = UserBlockingSchedulerPriority; + break; + case DefaultEventPriority: + schedulerPriority = NormalSchedulerPriority; + break; + case IdleEventPriority: + schedulerPriority = IdleSchedulerPriority; + break; + default: + schedulerPriority = NormalSchedulerPriority; + break; + } injectedHook.onCommitFiberRoot( rendererID, root, diff --git a/packages/react-reconciler/src/ReactFiberHooks.new.js b/packages/react-reconciler/src/ReactFiberHooks.new.js index 9a94ed1536d3..f47627053fc9 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.new.js +++ b/packages/react-reconciler/src/ReactFiberHooks.new.js @@ -41,7 +41,6 @@ import { import { NoLane, NoLanes, - InputContinuousLanePriority, isSubsetOfLanes, mergeLanes, removeLanes, @@ -49,11 +48,14 @@ import { isTransitionLane, markRootEntangled, markRootMutableRead, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, - higherLanePriority, - DefaultLanePriority, } from './ReactFiberLane.new'; +import { + DefaultEventPriority, + ContinuousEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, + higherEventPriority, +} from './ReactEventPriorities.new'; import {readContext, checkIfContextChanged} from './ReactFiberNewContext.new'; import {HostRoot, CacheComponent} from './ReactWorkTags'; import { @@ -1705,9 +1707,9 @@ function rerenderDeferredValue(value: T): T { } function startTransition(setPending, callback) { - const previousLanePriority = getCurrentUpdateLanePriority(); - setCurrentUpdateLanePriority( - higherLanePriority(previousLanePriority, InputContinuousLanePriority), + const previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority), ); setPending(true); @@ -1715,7 +1717,7 @@ function startTransition(setPending, callback) { // TODO: Can remove this. Was only necessary because we used to give // different behavior to transitions without a config object. Now they are // all treated the same. - setCurrentUpdateLanePriority(DefaultLanePriority); + setCurrentUpdatePriority(DefaultEventPriority); const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; @@ -1723,7 +1725,7 @@ function startTransition(setPending, callback) { setPending(false); callback(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); ReactCurrentBatchConfig.transition = prevTransition; } } diff --git a/packages/react-reconciler/src/ReactFiberHooks.old.js b/packages/react-reconciler/src/ReactFiberHooks.old.js index d705a58658d1..7673d88caecd 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.old.js +++ b/packages/react-reconciler/src/ReactFiberHooks.old.js @@ -41,7 +41,6 @@ import { import { NoLane, NoLanes, - InputContinuousLanePriority, isSubsetOfLanes, mergeLanes, removeLanes, @@ -49,11 +48,14 @@ import { isTransitionLane, markRootEntangled, markRootMutableRead, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, - higherLanePriority, - DefaultLanePriority, } from './ReactFiberLane.old'; +import { + DefaultEventPriority, + ContinuousEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, + higherEventPriority, +} from './ReactEventPriorities.old'; import {readContext, checkIfContextChanged} from './ReactFiberNewContext.old'; import {HostRoot, CacheComponent} from './ReactWorkTags'; import { @@ -1705,9 +1707,9 @@ function rerenderDeferredValue(value: T): T { } function startTransition(setPending, callback) { - const previousLanePriority = getCurrentUpdateLanePriority(); - setCurrentUpdateLanePriority( - higherLanePriority(previousLanePriority, InputContinuousLanePriority), + const previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority), ); setPending(true); @@ -1715,7 +1717,7 @@ function startTransition(setPending, callback) { // TODO: Can remove this. Was only necessary because we used to give // different behavior to transitions without a config object. Now they are // all treated the same. - setCurrentUpdateLanePriority(DefaultLanePriority); + setCurrentUpdatePriority(DefaultEventPriority); const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; @@ -1723,7 +1725,7 @@ function startTransition(setPending, callback) { setPending(false); callback(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); ReactCurrentBatchConfig.transition = prevTransition; } } diff --git a/packages/react-reconciler/src/ReactFiberLane.new.js b/packages/react-reconciler/src/ReactFiberLane.new.js index 01bcf19c91d8..5bca8d747b0c 100644 --- a/packages/react-reconciler/src/ReactFiberLane.new.js +++ b/packages/react-reconciler/src/ReactFiberLane.new.js @@ -73,8 +73,8 @@ export const NoLanePriority: LanePriority = 0; export const TotalLanes = 31; -export const NoLanes: Lanes = /* */ 0b000000000000000000000000000000; -export const NoLane: Lane = /* */ 0b000000000000000000000000000000; +export const NoLanes: Lanes = /* */ 0b0000000000000000000000000000000; +export const NoLane: Lane = /* */ 0b0000000000000000000000000000000; export const SyncLane: Lane = /* */ 0b0000000000000000000000000000001; @@ -168,19 +168,9 @@ export function getLabelsForLanes(lanes: Lanes): Array | void { export const NoTimestamp = -1; -let currentUpdateLanePriority: LanePriority = NoLanePriority; - let nextTransitionLane: Lane = TransitionLane1; let nextRetryLane: Lane = RetryLane1; -export function getCurrentUpdateLanePriority(): LanePriority { - return currentUpdateLanePriority; -} - -export function setCurrentUpdateLanePriority(newLanePriority: LanePriority) { - currentUpdateLanePriority = newLanePriority; -} - // "Registers" used to "return" multiple values // Used by getHighestPriorityLanes and getNextLanes: let return_highestLanePriority: LanePriority = DefaultLanePriority; @@ -532,35 +522,6 @@ export function isTransitionLane(lane: Lane) { return (lane & TransitionLanes) !== 0; } -// To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. -export function findUpdateLane(lanePriority: LanePriority): Lane { - switch (lanePriority) { - case NoLanePriority: - break; - case SyncLanePriority: - return SyncLane; - case InputContinuousLanePriority: - return InputContinuousLane; - case DefaultLanePriority: - return DefaultLane; - case TransitionPriority: // Should be handled by findTransitionLane instead - case RetryLanePriority: // Should be handled by findRetryLane instead - break; - case IdleLanePriority: - return IdleLane; - default: - // The remaining priorities are not valid for updates - break; - } - - invariant( - false, - 'Invalid update priority: %s. This is a bug in React.', - lanePriority, - ); -} - export function claimNextTransitionLane(): Lane { // Cycle through the lanes, assigning each new transition to the next lane. // In most cases, this means every transition gets its own lane, until we @@ -582,7 +543,7 @@ export function claimNextRetryLane(): Lane { return lane; } -function getHighestPriorityLane(lanes: Lanes) { +export function getHighestPriorityLane(lanes: Lanes): Lane { return lanes & -lanes; } diff --git a/packages/react-reconciler/src/ReactFiberLane.old.js b/packages/react-reconciler/src/ReactFiberLane.old.js index 90ffc0535968..6b9612034856 100644 --- a/packages/react-reconciler/src/ReactFiberLane.old.js +++ b/packages/react-reconciler/src/ReactFiberLane.old.js @@ -73,8 +73,8 @@ export const NoLanePriority: LanePriority = 0; export const TotalLanes = 31; -export const NoLanes: Lanes = /* */ 0b000000000000000000000000000000; -export const NoLane: Lane = /* */ 0b000000000000000000000000000000; +export const NoLanes: Lanes = /* */ 0b0000000000000000000000000000000; +export const NoLane: Lane = /* */ 0b0000000000000000000000000000000; export const SyncLane: Lane = /* */ 0b0000000000000000000000000000001; @@ -168,19 +168,9 @@ export function getLabelsForLanes(lanes: Lanes): Array | void { export const NoTimestamp = -1; -let currentUpdateLanePriority: LanePriority = NoLanePriority; - let nextTransitionLane: Lane = TransitionLane1; let nextRetryLane: Lane = RetryLane1; -export function getCurrentUpdateLanePriority(): LanePriority { - return currentUpdateLanePriority; -} - -export function setCurrentUpdateLanePriority(newLanePriority: LanePriority) { - currentUpdateLanePriority = newLanePriority; -} - // "Registers" used to "return" multiple values // Used by getHighestPriorityLanes and getNextLanes: let return_highestLanePriority: LanePriority = DefaultLanePriority; @@ -532,35 +522,6 @@ export function isTransitionLane(lane: Lane) { return (lane & TransitionLanes) !== 0; } -// To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. -export function findUpdateLane(lanePriority: LanePriority): Lane { - switch (lanePriority) { - case NoLanePriority: - break; - case SyncLanePriority: - return SyncLane; - case InputContinuousLanePriority: - return InputContinuousLane; - case DefaultLanePriority: - return DefaultLane; - case TransitionPriority: // Should be handled by findTransitionLane instead - case RetryLanePriority: // Should be handled by findRetryLane instead - break; - case IdleLanePriority: - return IdleLane; - default: - // The remaining priorities are not valid for updates - break; - } - - invariant( - false, - 'Invalid update priority: %s. This is a bug in React.', - lanePriority, - ); -} - export function claimNextTransitionLane(): Lane { // Cycle through the lanes, assigning each new transition to the next lane. // In most cases, this means every transition gets its own lane, until we @@ -582,7 +543,7 @@ export function claimNextRetryLane(): Lane { return lane; } -function getHighestPriorityLane(lanes: Lanes) { +export function getHighestPriorityLane(lanes: Lanes): Lane { return lanes & -lanes; } diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 56e517f9f53d..e789b58b61c1 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -51,7 +51,7 @@ import { observeVisibleRects as observeVisibleRects_old, registerMutableSourceForHydration as registerMutableSourceForHydration_old, runWithPriority as runWithPriority_old, - getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_old, + getCurrentUpdatePriority as getCurrentUpdatePriority_old, } from './ReactFiberReconciler.old'; import { @@ -91,7 +91,7 @@ import { observeVisibleRects as observeVisibleRects_new, registerMutableSourceForHydration as registerMutableSourceForHydration_new, runWithPriority as runWithPriority_new, - getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_new, + getCurrentUpdatePriority as getCurrentUpdatePriority_new, } from './ReactFiberReconciler.new'; export const createContainer = enableNewReconciler @@ -143,9 +143,9 @@ export const attemptContinuousHydration = enableNewReconciler export const attemptHydrationAtCurrentPriority = enableNewReconciler ? attemptHydrationAtCurrentPriority_new : attemptHydrationAtCurrentPriority_old; -export const getCurrentUpdateLanePriority = enableNewReconciler - ? getCurrentUpdateLanePriority_new - : getCurrentUpdateLanePriority_old; +export const getCurrentUpdatePriority = enableNewReconciler + ? getCurrentUpdatePriority_new + : getCurrentUpdatePriority_old; export const findHostInstance = enableNewReconciler ? findHostInstance_new : findHostInstance_old; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.new.js b/packages/react-reconciler/src/ReactFiberReconciler.new.js index 95b8f5b38977..bbe8810ff52d 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.new.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.new.js @@ -18,7 +18,7 @@ import type { } from './ReactFiberHostConfig'; import type {RendererInspectionConfig} from './ReactFiberHostConfig'; import type {ReactNodeList} from 'shared/ReactTypes'; -import type {Lane, LanePriority} from './ReactFiberLane.new'; +import type {Lane} from './ReactFiberLane.new'; import type {SuspenseState} from './ReactFiberSuspenseComponent.new'; import { @@ -82,9 +82,11 @@ import { NoTimestamp, getHighestPriorityPendingLanes, higherPriorityLane, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, } from './ReactFiberLane.new'; +import { + getCurrentUpdatePriority, + runWithPriority, +} from './ReactEventPriorities.new'; import { scheduleRefresh, scheduleRoot, @@ -442,17 +444,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void { markRetryLaneIfNotHydrated(fiber, lane); } -export function runWithPriority(priority: LanePriority, fn: () => T) { - const previousPriority = getCurrentUpdateLanePriority(); - try { - setCurrentUpdateLanePriority(priority); - return fn(); - } finally { - setCurrentUpdateLanePriority(previousPriority); - } -} - -export {getCurrentUpdateLanePriority}; +export {getCurrentUpdatePriority, runWithPriority}; export {findHostInstance}; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.old.js b/packages/react-reconciler/src/ReactFiberReconciler.old.js index d72c8f2c2b88..c6ced2f5be5b 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.old.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.old.js @@ -18,7 +18,7 @@ import type { } from './ReactFiberHostConfig'; import type {RendererInspectionConfig} from './ReactFiberHostConfig'; import type {ReactNodeList} from 'shared/ReactTypes'; -import type {Lane, LanePriority} from './ReactFiberLane.old'; +import type {Lane} from './ReactFiberLane.old'; import type {SuspenseState} from './ReactFiberSuspenseComponent.old'; import { @@ -82,9 +82,11 @@ import { NoTimestamp, getHighestPriorityPendingLanes, higherPriorityLane, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, } from './ReactFiberLane.old'; +import { + getCurrentUpdatePriority, + runWithPriority, +} from './ReactEventPriorities.old'; import { scheduleRefresh, scheduleRoot, @@ -442,17 +444,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void { markRetryLaneIfNotHydrated(fiber, lane); } -export function runWithPriority(priority: LanePriority, fn: () => T) { - const previousPriority = getCurrentUpdateLanePriority(); - try { - setCurrentUpdateLanePriority(priority); - return fn(); - } finally { - setCurrentUpdateLanePriority(previousPriority); - } -} - -export {getCurrentUpdateLanePriority}; +export {getCurrentUpdatePriority, runWithPriority}; export {findHostInstance}; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 0e57b678d570..e86cb6777c28 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -9,7 +9,7 @@ import type {Thenable, Wakeable} from 'shared/ReactTypes'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; -import type {Lanes, Lane, LanePriority} from './ReactFiberLane.new'; +import type {Lanes, Lane} from './ReactFiberLane.new'; import type {Interaction} from 'scheduler/src/Tracing'; import type {SuspenseState} from './ReactFiberSuspenseComponent.new'; import type {StackCursor} from './ReactFiberStack.new'; @@ -132,12 +132,10 @@ import { import { NoLanePriority, SyncLanePriority, - DefaultLanePriority, NoLanes, NoLane, SyncLane, NoTimestamp, - findUpdateLane, claimNextTransitionLane, claimNextRetryLane, includesSomeLane, @@ -150,8 +148,6 @@ import { includesOnlyTransitions, getNextLanes, returnNextLanesPriority, - setCurrentUpdateLanePriority, - getCurrentUpdateLanePriority, markStarvedLanesAsExpired, getLanesToRetrySynchronouslyOnError, getMostRecentEventTime, @@ -162,6 +158,14 @@ import { markRootFinished, lanePriorityToSchedulerPriority, } from './ReactFiberLane.new'; +import { + DiscreteEventPriority, + DefaultEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, + higherEventPriority, + lanesToEventPriority, +} from './ReactEventPriorities.new'; import {requestCurrentTransition, NoTransition} from './ReactFiberTransition'; import {beginWork as originalBeginWork} from './ReactFiberBeginWork.new'; import {completeWork} from './ReactFiberCompleteWork.new'; @@ -320,7 +324,6 @@ let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null; let rootDoesHavePassiveEffects: boolean = false; let rootWithPendingPassiveEffects: FiberRoot | null = null; -let pendingPassiveEffectsRenderPriority: LanePriority = NoLanePriority; let pendingPassiveEffectsLanes: Lanes = NoLanes; let pendingPassiveProfilerEffects: Array = []; @@ -423,9 +426,13 @@ export function requestUpdateLane(fiber: Fiber): Lane { // Updates originating inside certain React methods, like flushSync, have // their priority set by tracking it with a context variable. - const updateLanePriority = getCurrentUpdateLanePriority(); - if (updateLanePriority !== NoLanePriority) { - return findUpdateLane(updateLanePriority); + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. + const updateLane: Lane = (getCurrentUpdatePriority(): any); + if (updateLane !== NoLane) { + return updateLane; } // This update originated outside React. Ask the host environement for an @@ -433,7 +440,8 @@ export function requestUpdateLane(fiber: Fiber): Lane { // // The opaque type returned by the host config is internally a lane, so we can // use that directly. - const eventLane = getCurrentEventPriority(); + // TODO: Move this type conversion to the event priority module. + const eventLane: Lane = (getCurrentEventPriority(): any); return eventLane; } @@ -1056,12 +1064,12 @@ export function flushDiscreteUpdates() { } export function deferredUpdates(fn: () => A): A { - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(DefaultLanePriority); + setCurrentUpdatePriority(DefaultEventPriority); return fn(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); } } @@ -1102,12 +1110,12 @@ export function discreteUpdates( c: C, d: D, ): R { - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); return fn(a, b, c, d); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); if (executionContext === NoContext) { // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); @@ -1146,16 +1154,16 @@ export function flushSync(fn: A => R, a: A): R { } executionContext |= BatchedContext; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); if (fn) { return fn(a); } else { return (undefined: $FlowFixMe); } } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -1167,12 +1175,12 @@ export function flushSync(fn: A => R, a: A): R { export function flushControlled(fn: () => mixed): void { const prevExecutionContext = executionContext; executionContext |= BatchedContext; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); fn(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); executionContext = prevExecutionContext; if (executionContext === NoContext) { @@ -1663,12 +1671,14 @@ function completeUnitOfWork(unitOfWork: Fiber): void { } function commitRoot(root) { - const previousUpdateLanePriority = getCurrentUpdateLanePriority(); + // TODO: This no longer makes any sense. We already wrap the mutation and + // layout phases. Should be able to remove. + const previousUpdateLanePriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); commitRootImpl(root, previousUpdateLanePriority); } finally { - setCurrentUpdateLanePriority(previousUpdateLanePriority); + setCurrentUpdatePriority(previousUpdateLanePriority); } return null; @@ -1780,8 +1790,8 @@ function commitRootImpl(root, renderPriorityLevel) { NoFlags; if (subtreeHasEffects || rootHasEffect) { - const previousLanePriority = getCurrentUpdateLanePriority(); - setCurrentUpdateLanePriority(SyncLanePriority); + const previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); const prevExecutionContext = executionContext; executionContext |= CommitContext; @@ -1815,7 +1825,7 @@ function commitRootImpl(root, renderPriorityLevel) { } // The next phase is the mutation phase, where we mutate the host tree. - commitMutationEffects(root, renderPriorityLevel, finishedWork); + commitMutationEffects(root, finishedWork); if (shouldFireAfterActiveInstanceBlur) { afterActiveInstanceBlur(); @@ -1863,10 +1873,8 @@ function commitRootImpl(root, renderPriorityLevel) { } executionContext = prevExecutionContext; - if (previousLanePriority != null) { - // Reset the priority to the previous non-sync value. - setCurrentUpdateLanePriority(previousLanePriority); - } + // Reset the priority to the previous non-sync value. + setCurrentUpdatePriority(previousPriority); } else { // No effects. root.current = finishedWork; @@ -1886,10 +1894,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; - pendingPassiveEffectsRenderPriority = - renderPriorityLevel === NoLanePriority - ? DefaultLanePriority - : renderPriorityLevel; } // Read this again, since an effect might have updated it @@ -2003,18 +2007,17 @@ function commitRootImpl(root, renderPriorityLevel) { export function flushPassiveEffects(): boolean { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoLanePriority) { - const priorityLevel = - pendingPassiveEffectsRenderPriority > DefaultLanePriority - ? DefaultLanePriority - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoLanePriority; - const previousLanePriority = getCurrentUpdateLanePriority(); + if (pendingPassiveEffectsLanes !== NoLanes) { + const priority = higherEventPriority( + DefaultEventPriority, + lanesToEventPriority(pendingPassiveEffectsLanes), + ); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(priorityLevel); + setCurrentUpdatePriority(priority); return flushPassiveEffectsImpl(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); } } return false; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 8a77e6546766..7d452fe2699f 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -9,7 +9,7 @@ import type {Thenable, Wakeable} from 'shared/ReactTypes'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; -import type {Lanes, Lane, LanePriority} from './ReactFiberLane.old'; +import type {Lanes, Lane} from './ReactFiberLane.old'; import type {Interaction} from 'scheduler/src/Tracing'; import type {SuspenseState} from './ReactFiberSuspenseComponent.old'; import type {StackCursor} from './ReactFiberStack.old'; @@ -132,12 +132,10 @@ import { import { NoLanePriority, SyncLanePriority, - DefaultLanePriority, NoLanes, NoLane, SyncLane, NoTimestamp, - findUpdateLane, claimNextTransitionLane, claimNextRetryLane, includesSomeLane, @@ -150,8 +148,6 @@ import { includesOnlyTransitions, getNextLanes, returnNextLanesPriority, - setCurrentUpdateLanePriority, - getCurrentUpdateLanePriority, markStarvedLanesAsExpired, getLanesToRetrySynchronouslyOnError, getMostRecentEventTime, @@ -162,6 +158,14 @@ import { markRootFinished, lanePriorityToSchedulerPriority, } from './ReactFiberLane.old'; +import { + DiscreteEventPriority, + DefaultEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, + higherEventPriority, + lanesToEventPriority, +} from './ReactEventPriorities.old'; import {requestCurrentTransition, NoTransition} from './ReactFiberTransition'; import {beginWork as originalBeginWork} from './ReactFiberBeginWork.old'; import {completeWork} from './ReactFiberCompleteWork.old'; @@ -320,7 +324,6 @@ let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null; let rootDoesHavePassiveEffects: boolean = false; let rootWithPendingPassiveEffects: FiberRoot | null = null; -let pendingPassiveEffectsRenderPriority: LanePriority = NoLanePriority; let pendingPassiveEffectsLanes: Lanes = NoLanes; let pendingPassiveProfilerEffects: Array = []; @@ -423,9 +426,13 @@ export function requestUpdateLane(fiber: Fiber): Lane { // Updates originating inside certain React methods, like flushSync, have // their priority set by tracking it with a context variable. - const updateLanePriority = getCurrentUpdateLanePriority(); - if (updateLanePriority !== NoLanePriority) { - return findUpdateLane(updateLanePriority); + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. + const updateLane: Lane = (getCurrentUpdatePriority(): any); + if (updateLane !== NoLane) { + return updateLane; } // This update originated outside React. Ask the host environement for an @@ -433,7 +440,8 @@ export function requestUpdateLane(fiber: Fiber): Lane { // // The opaque type returned by the host config is internally a lane, so we can // use that directly. - const eventLane = getCurrentEventPriority(); + // TODO: Move this type conversion to the event priority module. + const eventLane: Lane = (getCurrentEventPriority(): any); return eventLane; } @@ -1056,12 +1064,12 @@ export function flushDiscreteUpdates() { } export function deferredUpdates(fn: () => A): A { - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(DefaultLanePriority); + setCurrentUpdatePriority(DefaultEventPriority); return fn(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); } } @@ -1102,12 +1110,12 @@ export function discreteUpdates( c: C, d: D, ): R { - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); return fn(a, b, c, d); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); if (executionContext === NoContext) { // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); @@ -1146,16 +1154,16 @@ export function flushSync(fn: A => R, a: A): R { } executionContext |= BatchedContext; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); if (fn) { return fn(a); } else { return (undefined: $FlowFixMe); } } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -1167,12 +1175,12 @@ export function flushSync(fn: A => R, a: A): R { export function flushControlled(fn: () => mixed): void { const prevExecutionContext = executionContext; executionContext |= BatchedContext; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); fn(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); executionContext = prevExecutionContext; if (executionContext === NoContext) { @@ -1663,12 +1671,14 @@ function completeUnitOfWork(unitOfWork: Fiber): void { } function commitRoot(root) { - const previousUpdateLanePriority = getCurrentUpdateLanePriority(); + // TODO: This no longer makes any sense. We already wrap the mutation and + // layout phases. Should be able to remove. + const previousUpdateLanePriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(SyncLanePriority); + setCurrentUpdatePriority(DiscreteEventPriority); commitRootImpl(root, previousUpdateLanePriority); } finally { - setCurrentUpdateLanePriority(previousUpdateLanePriority); + setCurrentUpdatePriority(previousUpdateLanePriority); } return null; @@ -1780,8 +1790,8 @@ function commitRootImpl(root, renderPriorityLevel) { NoFlags; if (subtreeHasEffects || rootHasEffect) { - const previousLanePriority = getCurrentUpdateLanePriority(); - setCurrentUpdateLanePriority(SyncLanePriority); + const previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); const prevExecutionContext = executionContext; executionContext |= CommitContext; @@ -1815,7 +1825,7 @@ function commitRootImpl(root, renderPriorityLevel) { } // The next phase is the mutation phase, where we mutate the host tree. - commitMutationEffects(root, renderPriorityLevel, finishedWork); + commitMutationEffects(root, finishedWork); if (shouldFireAfterActiveInstanceBlur) { afterActiveInstanceBlur(); @@ -1863,10 +1873,8 @@ function commitRootImpl(root, renderPriorityLevel) { } executionContext = prevExecutionContext; - if (previousLanePriority != null) { - // Reset the priority to the previous non-sync value. - setCurrentUpdateLanePriority(previousLanePriority); - } + // Reset the priority to the previous non-sync value. + setCurrentUpdatePriority(previousPriority); } else { // No effects. root.current = finishedWork; @@ -1886,10 +1894,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; - pendingPassiveEffectsRenderPriority = - renderPriorityLevel === NoLanePriority - ? DefaultLanePriority - : renderPriorityLevel; } // Read this again, since an effect might have updated it @@ -2003,18 +2007,17 @@ function commitRootImpl(root, renderPriorityLevel) { export function flushPassiveEffects(): boolean { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoLanePriority) { - const priorityLevel = - pendingPassiveEffectsRenderPriority > DefaultLanePriority - ? DefaultLanePriority - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoLanePriority; - const previousLanePriority = getCurrentUpdateLanePriority(); + if (pendingPassiveEffectsLanes !== NoLanes) { + const priority = higherEventPriority( + DefaultEventPriority, + lanesToEventPriority(pendingPassiveEffectsLanes), + ); + const previousPriority = getCurrentUpdatePriority(); try { - setCurrentUpdateLanePriority(priorityLevel); + setCurrentUpdatePriority(priority); return flushPassiveEffectsImpl(); } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousPriority); } } return false; diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js index 9efa57d327ef..685285dffd80 100644 --- a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js +++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js @@ -16,10 +16,10 @@ import {__interactionsRef} from 'scheduler/tracing'; import {enableSchedulerTracing} from 'shared/ReactFeatureFlags'; import invariant from 'shared/invariant'; import { - SyncLanePriority, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, -} from './ReactFiberLane.new'; + DiscreteEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, +} from './ReactEventPriorities.new'; const { unstable_scheduleCallback: Scheduler_scheduleCallback, @@ -147,11 +147,13 @@ export function flushSyncCallbackQueue() { // Prevent re-entrancy. isFlushingSyncQueue = true; let i = 0; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousUpdatePriority = getCurrentUpdatePriority(); try { const isSync = true; const queue = syncQueue; - setCurrentUpdateLanePriority(SyncLanePriority); + // TODO: Is this necessary anymore? The only user code that runs in this + // queue is in the render or commit phases. + setCurrentUpdatePriority(DiscreteEventPriority); for (; i < queue.length; i++) { let callback = queue[i]; do { @@ -171,7 +173,7 @@ export function flushSyncCallbackQueue() { ); throw error; } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousUpdatePriority); isFlushingSyncQueue = false; } } diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js index bde9672f329e..142b04333adb 100644 --- a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js +++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js @@ -16,10 +16,10 @@ import {__interactionsRef} from 'scheduler/tracing'; import {enableSchedulerTracing} from 'shared/ReactFeatureFlags'; import invariant from 'shared/invariant'; import { - SyncLanePriority, - getCurrentUpdateLanePriority, - setCurrentUpdateLanePriority, -} from './ReactFiberLane.old'; + DiscreteEventPriority, + getCurrentUpdatePriority, + setCurrentUpdatePriority, +} from './ReactEventPriorities.old'; const { unstable_scheduleCallback: Scheduler_scheduleCallback, @@ -147,11 +147,13 @@ export function flushSyncCallbackQueue() { // Prevent re-entrancy. isFlushingSyncQueue = true; let i = 0; - const previousLanePriority = getCurrentUpdateLanePriority(); + const previousUpdatePriority = getCurrentUpdatePriority(); try { const isSync = true; const queue = syncQueue; - setCurrentUpdateLanePriority(SyncLanePriority); + // TODO: Is this necessary anymore? The only user code that runs in this + // queue is in the render or commit phases. + setCurrentUpdatePriority(DiscreteEventPriority); for (; i < queue.length; i++) { let callback = queue[i]; do { @@ -171,7 +173,7 @@ export function flushSyncCallbackQueue() { ); throw error; } finally { - setCurrentUpdateLanePriority(previousLanePriority); + setCurrentUpdatePriority(previousUpdatePriority); isFlushingSyncQueue = false; } } diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js index ec587d7231c7..98092cf33ffa 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js @@ -13,11 +13,7 @@ let React; let ReactNoop; let Scheduler; - -// Copied from ReactFiberLanes. Don't do this! -// This is hard coded directly to avoid needing to import, and -// we'll remove this as we replace runWithPriority with React APIs. -const InputContinuousLanePriority = 10; +let ContinuousEventPriority; describe('ReactIncrementalUpdates', () => { beforeEach(() => { @@ -26,6 +22,8 @@ describe('ReactIncrementalUpdates', () => { React = require('react'); ReactNoop = require('react-noop-renderer'); Scheduler = require('scheduler'); + ContinuousEventPriority = require('react-reconciler/constants') + .ContinuousEventPriority; }); function span(prop) { @@ -544,7 +542,7 @@ describe('ReactIncrementalUpdates', () => { Scheduler.unstable_yieldValue('Committed: ' + log); if (log === 'B') { // Right after B commits, schedule additional updates. - ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () => + ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('C'), ); setLog(prevLog => prevLog + 'D'); @@ -564,7 +562,7 @@ describe('ReactIncrementalUpdates', () => { await ReactNoop.act(async () => { pushToLog('A'); - ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () => + ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), ); }); @@ -597,7 +595,7 @@ describe('ReactIncrementalUpdates', () => { Scheduler.unstable_yieldValue('Committed: ' + this.state.log); if (this.state.log === 'B') { // Right after B commits, schedule additional updates. - ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () => + ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => this.pushToLog('C'), ); this.pushToLog('D'); @@ -618,7 +616,7 @@ describe('ReactIncrementalUpdates', () => { await ReactNoop.act(async () => { pushToLog('A'); - ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () => + ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), ); }); diff --git a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js index 479e229d9115..249aeab17334 100644 --- a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js +++ b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js @@ -23,12 +23,8 @@ let onWorkCanceled; let onWorkScheduled; let onWorkStarted; let onWorkStopped; - -// Copied from ReactFiberLanes. Don't do this! -// This is hard coded directly to avoid needing to import, and -// we'll remove this as we replace runWithPriority with React APIs. -const IdleLanePriority = 2; -const InputContinuousPriority = 10; +let IdleEventPriority; +let ContinuousEventPriority; function loadModules() { ReactFeatureFlags = require('shared/ReactFeatureFlags'); @@ -44,6 +40,10 @@ function loadModules() { SchedulerTracing = require('scheduler/tracing'); TestUtils = require('react-dom/test-utils'); + IdleEventPriority = require('react-reconciler/constants').IdleEventPriority; + ContinuousEventPriority = require('react-reconciler/constants') + .ContinuousEventPriority; + act = TestUtils.unstable_concurrentAct; onInteractionScheduledWorkCompleted = jest.fn(); @@ -246,7 +246,7 @@ describe('ReactDOMTracing', () => { Scheduler.unstable_yieldValue('Child:update'); } else { Scheduler.unstable_yieldValue('Child:mount'); - ReactDOM.unstable_runWithPriority(IdleLanePriority, () => + ReactDOM.unstable_runWithPriority(IdleEventPriority, () => setDidMount(true), ); } @@ -499,7 +499,7 @@ describe('ReactDOMTracing', () => { let interaction = null; SchedulerTracing.unstable_trace('update', 0, () => { interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0]; - ReactDOM.unstable_runWithPriority(InputContinuousPriority, () => + ReactDOM.unstable_runWithPriority(ContinuousEventPriority, () => scheduleUpdateWithHidden(), ); }); @@ -606,7 +606,7 @@ describe('ReactDOMTracing', () => { // Schedule an unrelated low priority update that shouldn't be included // in the previous interaction. This is meant to ensure that we don't // rely on the whole tree completing to cover up bugs. - ReactDOM.unstable_runWithPriority(IdleLanePriority, () => { + ReactDOM.unstable_runWithPriority(IdleEventPriority, () => { root.render(); });