mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Schedule passive phase whenever there's a deletion (#20624)
We use the passive phase to detach the fibers.
This commit is contained in:
@@ -136,8 +136,6 @@ import {
|
||||
captureCommitPhaseError,
|
||||
resolveRetryWakeable,
|
||||
markCommitTimeOfFallback,
|
||||
enqueuePendingPassiveHookEffectMount,
|
||||
enqueuePendingPassiveHookEffectUnmount,
|
||||
enqueuePendingPassiveProfilerEffect,
|
||||
} from './ReactFiberWorkLoop.new';
|
||||
import {
|
||||
@@ -533,26 +531,6 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
|
||||
}
|
||||
}
|
||||
|
||||
function schedulePassiveEffects(finishedWork: Fiber) {
|
||||
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
|
||||
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
|
||||
if (lastEffect !== null) {
|
||||
const firstEffect = lastEffect.next;
|
||||
let effect = firstEffect;
|
||||
do {
|
||||
const {next, tag} = effect;
|
||||
if (
|
||||
(tag & HookPassive) !== NoHookEffect &&
|
||||
(tag & HookHasEffect) !== NoHookEffect
|
||||
) {
|
||||
enqueuePendingPassiveHookEffectUnmount(finishedWork, effect);
|
||||
enqueuePendingPassiveHookEffectMount(finishedWork, effect);
|
||||
}
|
||||
effect = next;
|
||||
} while (effect !== firstEffect);
|
||||
}
|
||||
}
|
||||
|
||||
export function commitPassiveEffectDurations(
|
||||
finishedRoot: FiberRoot,
|
||||
finishedWork: Fiber,
|
||||
@@ -639,8 +617,6 @@ function commitLayoutEffectOnFiber(
|
||||
} else {
|
||||
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
|
||||
}
|
||||
|
||||
schedulePassiveEffects(finishedWork);
|
||||
break;
|
||||
}
|
||||
case ClassComponent: {
|
||||
@@ -1091,9 +1067,7 @@ function commitUnmount(
|
||||
do {
|
||||
const {destroy, tag} = effect;
|
||||
if (destroy !== undefined) {
|
||||
if ((tag & HookPassive) !== NoHookEffect) {
|
||||
enqueuePendingPassiveHookEffectUnmount(current, effect);
|
||||
} else {
|
||||
if ((tag & HookLayout) !== NoHookEffect) {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
enableProfilerCommitHooks &&
|
||||
|
||||
@@ -81,6 +81,8 @@ export const MutationMask =
|
||||
Hydrating |
|
||||
Visibility;
|
||||
export const LayoutMask = Update | Callback | Ref;
|
||||
|
||||
// TODO: Split into PassiveMountMask and PassiveUnmountMask
|
||||
export const PassiveMask = Passive | ChildDeletion;
|
||||
|
||||
// Union of tags that don't get reset on clones.
|
||||
|
||||
@@ -472,6 +472,8 @@ export function bailoutHooks(
|
||||
lanes: Lanes,
|
||||
) {
|
||||
workInProgress.updateQueue = current.updateQueue;
|
||||
// TODO: Don't need to reset the flags here, because they're reset in the
|
||||
// complete phase (bubbleProperties).
|
||||
workInProgress.flags &= ~(PassiveEffect | UpdateEffect);
|
||||
current.lanes = removeLanes(current.lanes, lanes);
|
||||
}
|
||||
@@ -1309,7 +1311,7 @@ function mountEffect(
|
||||
}
|
||||
}
|
||||
return mountEffectImpl(
|
||||
UpdateEffect | PassiveEffect | PassiveStaticEffect,
|
||||
PassiveEffect | PassiveStaticEffect,
|
||||
HookPassive,
|
||||
create,
|
||||
deps,
|
||||
@@ -1326,12 +1328,7 @@ function updateEffect(
|
||||
warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);
|
||||
}
|
||||
}
|
||||
return updateEffectImpl(
|
||||
UpdateEffect | PassiveEffect,
|
||||
HookPassive,
|
||||
create,
|
||||
deps,
|
||||
);
|
||||
return updateEffectImpl(PassiveEffect, HookPassive, create, deps);
|
||||
}
|
||||
|
||||
function mountLayoutEffect(
|
||||
@@ -1683,7 +1680,7 @@ function mountOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const setId = mountState(id)[1];
|
||||
|
||||
if ((currentlyRenderingFiber.mode & BlockingMode) === NoMode) {
|
||||
currentlyRenderingFiber.flags |= UpdateEffect | PassiveEffect;
|
||||
currentlyRenderingFiber.flags |= PassiveEffect;
|
||||
pushEffect(
|
||||
HookHasEffect | HookPassive,
|
||||
() => {
|
||||
|
||||
@@ -13,7 +13,6 @@ import type {Lanes, Lane} from './ReactFiberLane.new';
|
||||
import type {ReactPriorityLevel} from './ReactInternalTypes';
|
||||
import type {Interaction} from 'scheduler/src/Tracing';
|
||||
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
|
||||
import type {Effect as HookEffect} from './ReactFiberHooks.new';
|
||||
import type {StackCursor} from './ReactFiberStack.new';
|
||||
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
|
||||
|
||||
@@ -120,12 +119,11 @@ import {
|
||||
NoFlags,
|
||||
PerformedWork,
|
||||
Placement,
|
||||
ChildDeletion,
|
||||
Passive,
|
||||
PassiveStatic,
|
||||
Incomplete,
|
||||
HostEffectMask,
|
||||
Hydrating,
|
||||
PassiveMask,
|
||||
StaticMask,
|
||||
} from './ReactFiberFlags';
|
||||
import {
|
||||
@@ -183,7 +181,6 @@ import {
|
||||
commitPassiveEffectDurations,
|
||||
commitPassiveMountEffects,
|
||||
commitPassiveUnmountEffects,
|
||||
detachFiberAfterEffects,
|
||||
} from './ReactFiberCommitWork.new';
|
||||
import {enqueueUpdate} from './ReactUpdateQueue.new';
|
||||
import {resetContextDependencies} from './ReactFiberNewContext.new';
|
||||
@@ -314,7 +311,6 @@ export function getRenderTargetTime(): number {
|
||||
return workInProgressRootRenderTargetTime;
|
||||
}
|
||||
|
||||
let nextEffect: Fiber | null = null;
|
||||
let hasUncaughtError = false;
|
||||
let firstUncaughtError = null;
|
||||
let legacyErrorBoundariesThatAlreadyFailed: Set<mixed> | null = null;
|
||||
@@ -1938,8 +1934,8 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||
// TODO: Delete all other places that schedule the passive effect callback
|
||||
// They're redundant.
|
||||
if (
|
||||
(finishedWork.subtreeFlags & Passive) !== NoFlags ||
|
||||
(finishedWork.flags & Passive) !== NoFlags
|
||||
(finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||
|
||||
(finishedWork.flags & PassiveMask) !== NoFlags
|
||||
) {
|
||||
if (!rootDoesHavePassiveEffects) {
|
||||
rootDoesHavePassiveEffects = true;
|
||||
@@ -2061,31 +2057,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||
rootWithPendingPassiveEffects = root;
|
||||
pendingPassiveEffectsLanes = lanes;
|
||||
pendingPassiveEffectsRenderPriority = renderPriorityLevel;
|
||||
} else {
|
||||
// We are done with the effect chain at this point so let's clear the
|
||||
// nextEffect pointers to assist with GC. If we have passive effects, we'll
|
||||
// clear this in flushPassiveEffects
|
||||
// TODO: We should always do this in the passive phase, by scheduling
|
||||
// a passive callback for every deletion.
|
||||
nextEffect = firstEffect;
|
||||
while (nextEffect !== null) {
|
||||
const nextNextEffect = nextEffect.nextEffect;
|
||||
nextEffect.nextEffect = null;
|
||||
if (nextEffect.flags & ChildDeletion) {
|
||||
const deletions = nextEffect.deletions;
|
||||
if (deletions !== null) {
|
||||
for (let i = 0; i < deletions.length; i++) {
|
||||
const deletion = deletions[i];
|
||||
const alternate = deletion.alternate;
|
||||
detachFiberAfterEffects(deletion);
|
||||
if (alternate !== null) {
|
||||
detachFiberAfterEffects(alternate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextEffect = nextNextEffect;
|
||||
}
|
||||
}
|
||||
|
||||
// Read this again, since an effect might have updated it
|
||||
@@ -2229,32 +2200,6 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function enqueuePendingPassiveHookEffectMount(
|
||||
fiber: Fiber,
|
||||
effect: HookEffect,
|
||||
): void {
|
||||
if (!rootDoesHavePassiveEffects) {
|
||||
rootDoesHavePassiveEffects = true;
|
||||
scheduleCallback(NormalSchedulerPriority, () => {
|
||||
flushPassiveEffects();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function enqueuePendingPassiveHookEffectUnmount(
|
||||
fiber: Fiber,
|
||||
effect: HookEffect,
|
||||
): void {
|
||||
if (!rootDoesHavePassiveEffects) {
|
||||
rootDoesHavePassiveEffects = true;
|
||||
scheduleCallback(NormalSchedulerPriority, () => {
|
||||
flushPassiveEffects();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function flushPassiveEffectsImpl() {
|
||||
if (rootWithPendingPassiveEffects === null) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user