mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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.
This commit is contained in:
@@ -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(<App text="Hi" className="hi" />);
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+5
-3
@@ -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;
|
||||
|
||||
+5
-24
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -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: <T>(priority: LanePriority, fn: () => T) => T;
|
||||
let attemptHydrationAtPriority: <T>(priority: EventPriority, fn: () => T) => T;
|
||||
|
||||
export function setAttemptHydrationAtPriority(
|
||||
fn: <T>(priority: LanePriority, fn: () => T) => T,
|
||||
fn: <T>(priority: EventPriority, fn: () => T) => T,
|
||||
) {
|
||||
attemptHydrationAtPriority = fn;
|
||||
}
|
||||
@@ -109,7 +110,7 @@ const queuedPointerCaptures: Map<number, QueuedReplayableEvent> = new Map();
|
||||
type QueuedHydrationTarget = {|
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
target: Node,
|
||||
lanePriority: LanePriority,
|
||||
priority: EventPriority,
|
||||
|};
|
||||
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+49
-12
@@ -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<T>(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));
|
||||
}
|
||||
|
||||
@@ -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<T>(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;
|
||||
}
|
||||
|
||||
@@ -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<T>(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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<T>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string> | 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<string> | 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;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -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;
|
||||
|
||||
@@ -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<T>(priority: LanePriority, fn: () => T) {
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(priority);
|
||||
return fn();
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
}
|
||||
|
||||
export {getCurrentUpdateLanePriority};
|
||||
export {getCurrentUpdatePriority, runWithPriority};
|
||||
|
||||
export {findHostInstance};
|
||||
|
||||
|
||||
@@ -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<T>(priority: LanePriority, fn: () => T) {
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(priority);
|
||||
return fn();
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
}
|
||||
|
||||
export {getCurrentUpdateLanePriority};
|
||||
export {getCurrentUpdatePriority, runWithPriority};
|
||||
|
||||
export {findHostInstance};
|
||||
|
||||
|
||||
@@ -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<Fiber> = [];
|
||||
|
||||
@@ -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<A>(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<A, B, C, D, R>(
|
||||
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<A, R>(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<A, R>(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;
|
||||
|
||||
@@ -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<Fiber> = [];
|
||||
|
||||
@@ -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<A>(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<A, B, C, D, R>(
|
||||
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<A, R>(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<A, R>(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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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(<App />);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user