Skip to content

Commit 741dcbd

Browse files
authored
Schedule passive phase whenever there's a deletion (#20624)
We use the passive phase to detach the fibers.
1 parent 11a983f commit 741dcbd

4 files changed

Lines changed: 11 additions & 93 deletions

File tree

‎packages/react-reconciler/src/ReactFiberCommitWork.new.js‎

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ import {
136136
captureCommitPhaseError,
137137
resolveRetryWakeable,
138138
markCommitTimeOfFallback,
139-
enqueuePendingPassiveHookEffectMount,
140-
enqueuePendingPassiveHookEffectUnmount,
141139
enqueuePendingPassiveProfilerEffect,
142140
}from'./ReactFiberWorkLoop.new';
143141
import{
@@ -533,26 +531,6 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
533531
}
534532
}
535533

536-
functionschedulePassiveEffects(finishedWork: Fiber){
537-
constupdateQueue: FunctionComponentUpdateQueue|null=(finishedWork.updateQueue: any);
538-
constlastEffect=updateQueue!==null ? updateQueue.lastEffect : null;
539-
if(lastEffect!==null){
540-
constfirstEffect=lastEffect.next;
541-
leteffect=firstEffect;
542-
do{
543-
const{next,tag}=effect;
544-
if(
545-
(tag&HookPassive)!==NoHookEffect&&
546-
(tag&HookHasEffect)!==NoHookEffect
547-
){
548-
enqueuePendingPassiveHookEffectUnmount(finishedWork,effect);
549-
enqueuePendingPassiveHookEffectMount(finishedWork,effect);
550-
}
551-
effect=next;
552-
}while(effect!==firstEffect);
553-
}
554-
}
555-
556534
exportfunctioncommitPassiveEffectDurations(
557535
finishedRoot: FiberRoot,
558536
finishedWork: Fiber,
@@ -639,8 +617,6 @@ function commitLayoutEffectOnFiber(
639617
}else{
640618
commitHookEffectListMount(HookLayout|HookHasEffect,finishedWork);
641619
}
642-
643-
schedulePassiveEffects(finishedWork);
644620
break;
645621
}
646622
caseClassComponent: {
@@ -1091,9 +1067,7 @@ function commitUnmount(
10911067
do{
10921068
const{destroy,tag}=effect;
10931069
if(destroy!==undefined){
1094-
if((tag&HookPassive)!==NoHookEffect){
1095-
enqueuePendingPassiveHookEffectUnmount(current,effect);
1096-
}else{
1070+
if((tag&HookLayout)!==NoHookEffect){
10971071
if(
10981072
enableProfilerTimer&&
10991073
enableProfilerCommitHooks&&

‎packages/react-reconciler/src/ReactFiberFlags.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ export const MutationMask =
8181
Hydrating|
8282
Visibility;
8383
exportconstLayoutMask=Update|Callback|Ref;
84+
85+
// TODO: Split into PassiveMountMask and PassiveUnmountMask
8486
exportconstPassiveMask=Passive|ChildDeletion;
8587

8688
// Union of tags that don't get reset on clones.

‎packages/react-reconciler/src/ReactFiberHooks.new.js‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ export function bailoutHooks(
472472
lanes: Lanes,
473473
){
474474
workInProgress.updateQueue=current.updateQueue;
475+
// TODO: Don't need to reset the flags here, because they're reset in the
476+
// complete phase (bubbleProperties).
475477
workInProgress.flags&=~(PassiveEffect|UpdateEffect);
476478
current.lanes=removeLanes(current.lanes,lanes);
477479
}
@@ -1309,7 +1311,7 @@ function mountEffect(
13091311
}
13101312
}
13111313
returnmountEffectImpl(
1312-
UpdateEffect|PassiveEffect|PassiveStaticEffect,
1314+
PassiveEffect|PassiveStaticEffect,
13131315
HookPassive,
13141316
create,
13151317
deps,
@@ -1326,12 +1328,7 @@ function updateEffect(
13261328
warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);
13271329
}
13281330
}
1329-
returnupdateEffectImpl(
1330-
UpdateEffect|PassiveEffect,
1331-
HookPassive,
1332-
create,
1333-
deps,
1334-
);
1331+
returnupdateEffectImpl(PassiveEffect, HookPassive, create, deps);
13351332
}
13361333

13371334
functionmountLayoutEffect(
@@ -1683,7 +1680,7 @@ function mountOpaqueIdentifier(): OpaqueIDType | void {
16831680
constsetId=mountState(id)[1];
16841681

16851682
if((currentlyRenderingFiber.mode&BlockingMode)===NoMode){
1686-
currentlyRenderingFiber.flags|=UpdateEffect|PassiveEffect;
1683+
currentlyRenderingFiber.flags|=PassiveEffect;
16871684
pushEffect(
16881685
HookHasEffect|HookPassive,
16891686
()=>{

‎packages/react-reconciler/src/ReactFiberWorkLoop.new.js‎

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import type {Lanes, Lane} from './ReactFiberLane.new';
1313
importtype{ReactPriorityLevel}from'./ReactInternalTypes';
1414
importtype{Interaction}from'scheduler/src/Tracing';
1515
importtype{SuspenseState}from'./ReactFiberSuspenseComponent.new';
16-
importtype{EffectasHookEffect}from'./ReactFiberHooks.new';
1716
importtype{StackCursor}from'./ReactFiberStack.new';
1817
importtype{FunctionComponentUpdateQueue}from'./ReactFiberHooks.new';
1918

@@ -120,12 +119,11 @@ import {
120119
NoFlags,
121120
PerformedWork,
122121
Placement,
123-
ChildDeletion,
124-
Passive,
125122
PassiveStatic,
126123
Incomplete,
127124
HostEffectMask,
128125
Hydrating,
126+
PassiveMask,
129127
StaticMask,
130128
}from'./ReactFiberFlags';
131129
import{
@@ -183,7 +181,6 @@ import {
183181
commitPassiveEffectDurations,
184182
commitPassiveMountEffects,
185183
commitPassiveUnmountEffects,
186-
detachFiberAfterEffects,
187184
}from'./ReactFiberCommitWork.new';
188185
import{enqueueUpdate}from'./ReactUpdateQueue.new';
189186
import{resetContextDependencies}from'./ReactFiberNewContext.new';
@@ -314,7 +311,6 @@ export function getRenderTargetTime(): number {
314311
returnworkInProgressRootRenderTargetTime;
315312
}
316313

317-
let nextEffect: Fiber | null = null;
318314
let hasUncaughtError = false;
319315
let firstUncaughtError = null;
320316
let legacyErrorBoundariesThatAlreadyFailed: Set<mixed> | null = null;
@@ -1938,8 +1934,8 @@ function commitRootImpl(root, renderPriorityLevel) {
19381934
// TODO: Delete all other places that schedule the passive effect callback
19391935
// They're redundant.
19401936
if(
1941-
(finishedWork.subtreeFlags&Passive)!==NoFlags||
1942-
(finishedWork.flags&Passive)!==NoFlags
1937+
(finishedWork.subtreeFlags&PassiveMask)!==NoFlags||
1938+
(finishedWork.flags&PassiveMask)!==NoFlags
19431939
){
19441940
if(!rootDoesHavePassiveEffects){
19451941
rootDoesHavePassiveEffects=true;
@@ -2061,31 +2057,6 @@ function commitRootImpl(root, renderPriorityLevel) {
20612057
rootWithPendingPassiveEffects=root;
20622058
pendingPassiveEffectsLanes=lanes;
20632059
pendingPassiveEffectsRenderPriority=renderPriorityLevel;
2064-
}else{
2065-
// We are done with the effect chain at this point so let's clear the
2066-
// nextEffect pointers to assist with GC. If we have passive effects, we'll
2067-
// clear this in flushPassiveEffects
2068-
// TODO: We should always do this in the passive phase, by scheduling
2069-
// a passive callback for every deletion.
2070-
nextEffect=firstEffect;
2071-
while(nextEffect!==null){
2072-
constnextNextEffect=nextEffect.nextEffect;
2073-
nextEffect.nextEffect=null;
2074-
if(nextEffect.flags&ChildDeletion){
2075-
constdeletions=nextEffect.deletions;
2076-
if(deletions!==null){
2077-
for(leti=0;i<deletions.length;i++){
2078-
constdeletion=deletions[i];
2079-
constalternate=deletion.alternate;
2080-
detachFiberAfterEffects(deletion);
2081-
if(alternate!==null){
2082-
detachFiberAfterEffects(alternate);
2083-
}
2084-
}
2085-
}
2086-
}
2087-
nextEffect=nextNextEffect;
2088-
}
20892060
}
20902061

20912062
// Read this again, since an effect might have updated it
@@ -2229,32 +2200,6 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
22292200
}
22302201
}
22312202

2232-
exportfunctionenqueuePendingPassiveHookEffectMount(
2233-
fiber: Fiber,
2234-
effect: HookEffect,
2235-
): void{
2236-
if(!rootDoesHavePassiveEffects){
2237-
rootDoesHavePassiveEffects=true;
2238-
scheduleCallback(NormalSchedulerPriority,()=>{
2239-
flushPassiveEffects();
2240-
returnnull;
2241-
});
2242-
}
2243-
}
2244-
2245-
exportfunctionenqueuePendingPassiveHookEffectUnmount(
2246-
fiber: Fiber,
2247-
effect: HookEffect,
2248-
): void{
2249-
if(!rootDoesHavePassiveEffects){
2250-
rootDoesHavePassiveEffects=true;
2251-
scheduleCallback(NormalSchedulerPriority,()=>{
2252-
flushPassiveEffects();
2253-
returnnull;
2254-
});
2255-
}
2256-
}
2257-
22582203
functionflushPassiveEffectsImpl(){
22592204
if(rootWithPendingPassiveEffects===null){
22602205
returnfalse;

0 commit comments

Comments
 (0)