Switch callsites over to update lane priority

This commit is contained in:
Rick Hanlon
2021-03-08 12:49:57 -07:00
parent e89d74ee67
commit 431e76e2db
7 changed files with 102 additions and 216 deletions
@@ -17,12 +17,11 @@ import type {
} from './ReactFiberHostConfig';
import type {Fiber} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {Lanes} from './ReactFiberLane.new';
import type {LanePriority, Lanes} from './ReactFiberLane.new';
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
import type {UpdateQueue} from './ReactUpdateQueue.new';
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
import type {Wakeable} from 'shared/ReactTypes';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {OffscreenState} from './ReactFiberOffscreenComponent';
import type {HookFlags} from './ReactHookEffectTags';
@@ -1057,7 +1056,7 @@ function commitUnmount(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
): void {
onCommitUnmount(current);
@@ -1153,7 +1152,7 @@ function commitNestedUnmounts(
finishedRoot: FiberRoot,
root: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
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
@@ -1463,7 +1462,7 @@ function unmountHostComponents(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
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.
@@ -1601,7 +1600,7 @@ function commitDeletion(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
): void {
if (supportsMutation) {
// Recursively delete all host nodes from the parent.
@@ -1945,7 +1944,7 @@ function commitResetTextContent(current: Fiber) {
export function commitMutationEffects(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
firstChild: Fiber,
) {
nextEffect = firstChild;
@@ -1954,7 +1953,7 @@ export function commitMutationEffects(
function commitMutationEffects_begin(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
@@ -2000,7 +1999,7 @@ function commitMutationEffects_begin(
function commitMutationEffects_complete(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
@@ -2041,7 +2040,7 @@ function commitMutationEffects_complete(
function commitMutationEffectsOnFiber(
finishedWork: Fiber,
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
const flags = finishedWork.flags;
@@ -17,12 +17,11 @@ import type {
} from './ReactFiberHostConfig';
import type {Fiber} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {Lanes} from './ReactFiberLane.old';
import type {LanePriority, Lanes} from './ReactFiberLane.old';
import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
import type {UpdateQueue} from './ReactUpdateQueue.old';
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.old';
import type {Wakeable} from 'shared/ReactTypes';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {OffscreenState} from './ReactFiberOffscreenComponent';
import type {HookFlags} from './ReactHookEffectTags';
@@ -1057,7 +1056,7 @@ function commitUnmount(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
): void {
onCommitUnmount(current);
@@ -1153,7 +1152,7 @@ function commitNestedUnmounts(
finishedRoot: FiberRoot,
root: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
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
@@ -1463,7 +1462,7 @@ function unmountHostComponents(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
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.
@@ -1601,7 +1600,7 @@ function commitDeletion(
finishedRoot: FiberRoot,
current: Fiber,
nearestMountedAncestor: Fiber,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
): void {
if (supportsMutation) {
// Recursively delete all host nodes from the parent.
@@ -1945,7 +1944,7 @@ function commitResetTextContent(current: Fiber) {
export function commitMutationEffects(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
firstChild: Fiber,
) {
nextEffect = firstChild;
@@ -1954,7 +1953,7 @@ export function commitMutationEffects(
function commitMutationEffects_begin(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
@@ -2000,7 +1999,7 @@ function commitMutationEffects_begin(
function commitMutationEffects_complete(
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
while (nextEffect !== null) {
const fiber = nextEffect;
@@ -2041,7 +2040,7 @@ function commitMutationEffects_complete(
function commitMutationEffectsOnFiber(
finishedWork: Fiber,
root: FiberRoot,
renderPriorityLevel: ReactPriorityLevel,
renderPriorityLevel: LanePriority,
) {
const flags = finishedWork.flags;
@@ -9,10 +9,16 @@
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
import type {Fiber, FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
import type {Fiber, FiberRoot} from './ReactInternalTypes';
import type {ReactNodeList} from 'shared/ReactTypes';
import type {LanePriority} from './ReactFiberLane.new';
import {DidCapture} from './ReactFiberFlags';
import {
lanePriorityToSchedulerPriority,
NoLanePriority,
} from './ReactFiberLane.new';
import {NormalPriority} from './SchedulerWithReactIntegration.new';
declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
@@ -78,18 +84,19 @@ export function onScheduleRoot(root: FiberRoot, children: ReactNodeList) {
}
}
export function onCommitRoot(
root: FiberRoot,
priorityLevel: ReactPriorityLevel,
) {
export function onCommitRoot(root: FiberRoot, priorityLevel: LanePriority) {
if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
try {
const didError = (root.current.flags & DidCapture) === DidCapture;
if (enableProfilerTimer) {
const schedulerPriority =
priorityLevel === NoLanePriority
? NormalPriority
: lanePriorityToSchedulerPriority(priorityLevel);
injectedHook.onCommitFiberRoot(
rendererID,
root,
priorityLevel,
schedulerPriority,
didError,
);
} else {
@@ -9,10 +9,16 @@
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
import type {Fiber, FiberRoot, ReactPriorityLevel} from './ReactInternalTypes';
import type {Fiber, FiberRoot} from './ReactInternalTypes';
import type {ReactNodeList} from 'shared/ReactTypes';
import type {LanePriority} from './ReactFiberLane.old';
import {DidCapture} from './ReactFiberFlags';
import {
lanePriorityToSchedulerPriority,
NoLanePriority,
} from './ReactFiberLane.old';
import {NormalPriority} from './SchedulerWithReactIntegration.old';
declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
@@ -78,18 +84,19 @@ export function onScheduleRoot(root: FiberRoot, children: ReactNodeList) {
}
}
export function onCommitRoot(
root: FiberRoot,
priorityLevel: ReactPriorityLevel,
) {
export function onCommitRoot(root: FiberRoot, priorityLevel: LanePriority) {
if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
try {
const didError = (root.current.flags & DidCapture) === DidCapture;
if (enableProfilerTimer) {
const schedulerPriority =
priorityLevel === NoLanePriority
? NormalPriority
: lanePriorityToSchedulerPriority(priorityLevel);
injectedHook.onCommitFiberRoot(
rendererID,
root,
priorityLevel,
schedulerPriority,
didError,
);
} else {
@@ -9,8 +9,7 @@
import type {Thenable, Wakeable} from 'shared/ReactTypes';
import type {Fiber, FiberRoot} from './ReactInternalTypes';
import type {Lanes, Lane} from './ReactFiberLane.new';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {Lanes, Lane, LanePriority} from './ReactFiberLane.new';
import type {Interaction} from 'scheduler/src/Tracing';
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
import type {StackCursor} from './ReactFiberStack.new';
@@ -46,7 +45,6 @@ import {
shouldYield,
requestPaint,
now,
NoPriority as NoSchedulerPriority,
ImmediatePriority as ImmediateSchedulerPriority,
UserBlockingPriority as UserBlockingSchedulerPriority,
NormalPriority as NormalSchedulerPriority,
@@ -173,6 +171,7 @@ import {
markRootFinished,
schedulerPriorityToLanePriority,
lanePriorityToSchedulerPriority,
higherLanePriority,
} from './ReactFiberLane.new';
import {requestCurrentTransition, NoTransition} from './ReactFiberTransition';
import {beginWork as originalBeginWork} from './ReactFiberBeginWork.new';
@@ -333,7 +332,7 @@ let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null;
let rootDoesHavePassiveEffects: boolean = false;
let rootWithPendingPassiveEffects: FiberRoot | null = null;
let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoSchedulerPriority;
let pendingPassiveEffectsRenderPriority: LanePriority = NoLanePriority;
let pendingPassiveEffectsLanes: Lanes = NoLanes;
let pendingPassiveProfilerEffects: Array<Fiber> = [];
@@ -394,7 +393,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
if ((mode & BlockingMode) === NoMode) {
return (SyncLane: Lane);
} else if ((mode & ConcurrentMode) === NoMode) {
return getCurrentPriorityLevel() === ImmediateSchedulerPriority
return getCurrentUpdateLanePriority() === SyncLanePriority
? (SyncLane: Lane)
: (SyncBatchedLane: Lane);
} else if (
@@ -482,7 +481,7 @@ function requestRetryLane(fiber: Fiber) {
if ((mode & BlockingMode) === NoMode) {
return (SyncLane: Lane);
} else if ((mode & ConcurrentMode) === NoMode) {
return getCurrentPriorityLevel() === ImmediateSchedulerPriority
return getCurrentUpdateLanePriority() === SyncLanePriority
? (SyncLane: Lane)
: (SyncBatchedLane: Lane);
}
@@ -596,9 +595,9 @@ export function scheduleUpdateOnFiber(
// Schedule a discrete update but only if it's not Sync.
if (
(executionContext & DiscreteEventContext) !== NoContext &&
// Only updates at user-blocking priority or greater are considered
// discrete, even inside a discrete event.
updateLanePriority === InputDiscreteLanePriority
// Only updates greater than default considered discrete, even inside a discrete event.
higherLanePriority(updateLanePriority, DefaultLanePriority) !==
DefaultLanePriority
) {
// This is the result of a discrete event. Track the lowest priority
// discrete update per root so we can flush them early, if needed.
@@ -1751,11 +1750,17 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
}
function commitRoot(root) {
const renderPriorityLevel = getCurrentPriorityLevel();
runWithPriority(
ImmediateSchedulerPriority,
commitRootImpl.bind(null, root, renderPriorityLevel),
);
const previousUpdateLanePriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(SyncLanePriority);
runWithPriority(
ImmediateSchedulerPriority,
commitRootImpl.bind(null, root, previousUpdateLanePriority),
);
} finally {
setCurrentUpdateLanePriority(previousUpdateLanePriority);
}
return null;
}
@@ -1983,7 +1988,10 @@ function commitRootImpl(root, renderPriorityLevel) {
rootDoesHavePassiveEffects = false;
rootWithPendingPassiveEffects = root;
pendingPassiveEffectsLanes = lanes;
pendingPassiveEffectsRenderPriority = renderPriorityLevel;
pendingPassiveEffectsRenderPriority =
renderPriorityLevel === NoLanePriority
? DefaultLanePriority
: renderPriorityLevel;
}
// Read this again, since an effect might have updated it
@@ -2097,18 +2105,16 @@ function commitRootImpl(root, renderPriorityLevel) {
export function flushPassiveEffects(): boolean {
// Returns whether passive effects were flushed.
if (pendingPassiveEffectsRenderPriority !== NoSchedulerPriority) {
if (pendingPassiveEffectsRenderPriority !== NoLanePriority) {
const priorityLevel =
pendingPassiveEffectsRenderPriority > NormalSchedulerPriority
? NormalSchedulerPriority
pendingPassiveEffectsRenderPriority > DefaultLanePriority
? DefaultLanePriority
: pendingPassiveEffectsRenderPriority;
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
pendingPassiveEffectsRenderPriority = NoLanePriority;
const previousLanePriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(
schedulerPriorityToLanePriority(priorityLevel),
);
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
setCurrentUpdateLanePriority(priorityLevel);
return flushPassiveEffectsImpl();
} finally {
setCurrentUpdateLanePriority(previousLanePriority);
}
@@ -9,8 +9,7 @@
import type {Thenable, Wakeable} from 'shared/ReactTypes';
import type {Fiber, FiberRoot} from './ReactInternalTypes';
import type {Lanes, Lane} from './ReactFiberLane.old';
import type {ReactPriorityLevel} from './ReactInternalTypes';
import type {Lanes, Lane, LanePriority} from './ReactFiberLane.old';
import type {Interaction} from 'scheduler/src/Tracing';
import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
import type {StackCursor} from './ReactFiberStack.old';
@@ -46,7 +45,6 @@ import {
shouldYield,
requestPaint,
now,
NoPriority as NoSchedulerPriority,
ImmediatePriority as ImmediateSchedulerPriority,
UserBlockingPriority as UserBlockingSchedulerPriority,
NormalPriority as NormalSchedulerPriority,
@@ -173,6 +171,7 @@ import {
markRootFinished,
schedulerPriorityToLanePriority,
lanePriorityToSchedulerPriority,
higherLanePriority,
} from './ReactFiberLane.old';
import {requestCurrentTransition, NoTransition} from './ReactFiberTransition';
import {beginWork as originalBeginWork} from './ReactFiberBeginWork.old';
@@ -333,7 +332,7 @@ let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null;
let rootDoesHavePassiveEffects: boolean = false;
let rootWithPendingPassiveEffects: FiberRoot | null = null;
let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoSchedulerPriority;
let pendingPassiveEffectsRenderPriority: LanePriority = NoLanePriority;
let pendingPassiveEffectsLanes: Lanes = NoLanes;
let pendingPassiveProfilerEffects: Array<Fiber> = [];
@@ -394,7 +393,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
if ((mode & BlockingMode) === NoMode) {
return (SyncLane: Lane);
} else if ((mode & ConcurrentMode) === NoMode) {
return getCurrentPriorityLevel() === ImmediateSchedulerPriority
return getCurrentUpdateLanePriority() === SyncLanePriority
? (SyncLane: Lane)
: (SyncBatchedLane: Lane);
} else if (
@@ -482,7 +481,7 @@ function requestRetryLane(fiber: Fiber) {
if ((mode & BlockingMode) === NoMode) {
return (SyncLane: Lane);
} else if ((mode & ConcurrentMode) === NoMode) {
return getCurrentPriorityLevel() === ImmediateSchedulerPriority
return getCurrentUpdateLanePriority() === SyncLanePriority
? (SyncLane: Lane)
: (SyncBatchedLane: Lane);
}
@@ -596,9 +595,9 @@ export function scheduleUpdateOnFiber(
// Schedule a discrete update but only if it's not Sync.
if (
(executionContext & DiscreteEventContext) !== NoContext &&
// Only updates at user-blocking priority or greater are considered
// discrete, even inside a discrete event.
updateLanePriority === InputDiscreteLanePriority
// Only updates greater than default considered discrete, even inside a discrete event.
higherLanePriority(updateLanePriority, DefaultLanePriority) !==
DefaultLanePriority
) {
// This is the result of a discrete event. Track the lowest priority
// discrete update per root so we can flush them early, if needed.
@@ -1751,11 +1750,17 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
}
function commitRoot(root) {
const renderPriorityLevel = getCurrentPriorityLevel();
runWithPriority(
ImmediateSchedulerPriority,
commitRootImpl.bind(null, root, renderPriorityLevel),
);
const previousUpdateLanePriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(SyncLanePriority);
runWithPriority(
ImmediateSchedulerPriority,
commitRootImpl.bind(null, root, previousUpdateLanePriority),
);
} finally {
setCurrentUpdateLanePriority(previousUpdateLanePriority);
}
return null;
}
@@ -1983,7 +1988,10 @@ function commitRootImpl(root, renderPriorityLevel) {
rootDoesHavePassiveEffects = false;
rootWithPendingPassiveEffects = root;
pendingPassiveEffectsLanes = lanes;
pendingPassiveEffectsRenderPriority = renderPriorityLevel;
pendingPassiveEffectsRenderPriority =
renderPriorityLevel === NoLanePriority
? DefaultLanePriority
: renderPriorityLevel;
}
// Read this again, since an effect might have updated it
@@ -2097,18 +2105,16 @@ function commitRootImpl(root, renderPriorityLevel) {
export function flushPassiveEffects(): boolean {
// Returns whether passive effects were flushed.
if (pendingPassiveEffectsRenderPriority !== NoSchedulerPriority) {
if (pendingPassiveEffectsRenderPriority !== NoLanePriority) {
const priorityLevel =
pendingPassiveEffectsRenderPriority > NormalSchedulerPriority
? NormalSchedulerPriority
pendingPassiveEffectsRenderPriority > DefaultLanePriority
? DefaultLanePriority
: pendingPassiveEffectsRenderPriority;
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
pendingPassiveEffectsRenderPriority = NoLanePriority;
const previousLanePriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(
schedulerPriorityToLanePriority(priorityLevel),
);
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
setCurrentUpdateLanePriority(priorityLevel);
return flushPassiveEffectsImpl();
} finally {
setCurrentUpdateLanePriority(previousLanePriority);
}
@@ -160,144 +160,6 @@ describe('ReactSchedulerIntegration', () => {
]);
});
// TODO: Figure out what to do with these tests. I don't think most of them
// make sense once we decouple Scheduler from React. Perhaps need similar
// tests for React DOM.
// @gate !enableNativeEventPriorityInference
it('passive effects never have higher than normal priority', async () => {
const {useEffect} = React;
function ReadPriority({step}) {
Scheduler.unstable_yieldValue(
`Render priority: ${getCurrentPriorityAsString()}`,
);
useEffect(() => {
Scheduler.unstable_yieldValue(
`Effect priority: ${getCurrentPriorityAsString()}`,
);
return () => {
Scheduler.unstable_yieldValue(
`Effect clean-up priority: ${getCurrentPriorityAsString()}`,
);
};
});
return null;
}
// High priority renders spawn effects at normal priority
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(ImmediatePriority, () => {
ReactNoop.render(<ReadPriority />);
});
});
expect(Scheduler).toHaveYielded([
'Render priority: Immediate',
'Effect priority: Normal',
]);
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(UserBlockingPriority, () => {
ReactNoop.render(<ReadPriority />);
});
});
expect(Scheduler).toHaveYielded([
'Render priority: UserBlocking',
'Effect clean-up priority: Normal',
'Effect priority: Normal',
]);
// Renders lower than normal priority spawn effects at the same priority
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(IdlePriority, () => {
ReactNoop.render(<ReadPriority />);
});
});
expect(Scheduler).toHaveYielded([
'Render priority: Idle',
'Effect clean-up priority: Idle',
'Effect priority: Idle',
]);
});
// TODO: Figure out what to do with these tests. I don't think most of them
// make sense once we decouple Scheduler from React. Perhaps need similar
// tests for React DOM.
// @gate !enableNativeEventPriorityInference
it('passive effects have correct priority even if they are flushed early', async () => {
const {useEffect} = React;
function ReadPriority({step}) {
Scheduler.unstable_yieldValue(
`Render priority [step ${step}]: ${getCurrentPriorityAsString()}`,
);
useEffect(() => {
Scheduler.unstable_yieldValue(
`Effect priority [step ${step}]: ${getCurrentPriorityAsString()}`,
);
});
return null;
}
await ReactNoop.act(async () => {
ReactNoop.render(<ReadPriority step={1} />);
Scheduler.unstable_flushUntilNextPaint();
expect(Scheduler).toHaveYielded(['Render priority [step 1]: Normal']);
Scheduler.unstable_runWithPriority(UserBlockingPriority, () => {
ReactNoop.render(<ReadPriority step={2} />);
});
});
expect(Scheduler).toHaveYielded([
'Effect priority [step 1]: Normal',
'Render priority [step 2]: UserBlocking',
'Effect priority [step 2]: Normal',
]);
});
// TODO: Figure out what to do with these tests. I don't think most of them
// make sense once we decouple Scheduler from React. Perhaps need similar
// tests for React DOM.
// @gate !enableNativeEventPriorityInference
it('passive effect clean-up functions have correct priority even when component is deleted', async () => {
const {useEffect} = React;
function ReadPriority({step}) {
useEffect(() => {
return () => {
Scheduler.unstable_yieldValue(
`Effect clean-up priority: ${getCurrentPriorityAsString()}`,
);
};
});
return null;
}
await ReactNoop.act(async () => {
ReactNoop.render(<ReadPriority />);
});
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(ImmediatePriority, () => {
ReactNoop.render(null);
});
});
expect(Scheduler).toHaveYielded(['Effect clean-up priority: Normal']);
await ReactNoop.act(async () => {
ReactNoop.render(<ReadPriority />);
});
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(UserBlockingPriority, () => {
ReactNoop.render(null);
});
});
expect(Scheduler).toHaveYielded(['Effect clean-up priority: Normal']);
// Renders lower than normal priority spawn effects at the same priority
await ReactNoop.act(async () => {
ReactNoop.render(<ReadPriority />);
});
await ReactNoop.act(async () => {
Scheduler.unstable_runWithPriority(IdlePriority, () => {
ReactNoop.render(null);
});
});
expect(Scheduler).toHaveYielded(['Effect clean-up priority: Idle']);
});
it('passive effects are called before Normal-pri scheduled in layout effects', async () => {
const {useEffect, useLayoutEffect} = React;
function Effects({step}) {