@@ -2406,15 +2406,16 @@ function commitMutationEffects(
24062406) {
24072407 let fiber = firstChild ;
24082408 while ( fiber !== null ) {
2409- if ( fiber . deletions !== null ) {
2410- commitMutationEffectsDeletions (
2411- fiber . deletions ,
2412- root ,
2413- renderPriorityLevel ,
2414- ) ;
2409+ const deletions = fiber . deletions ;
2410+ if ( deletions !== null ) {
2411+ commitMutationEffectsDeletions ( deletions , root , renderPriorityLevel ) ;
24152412
2416- // TODO (effects) Detach sibling pointers for deleted Fibers
2417- // TODO (effects) Clear deletion arrays
2413+ // If there are no pending passive effects, clear the deletions Array.
2414+ const primaryEffectTag = fiber . effectTag & PassiveMask ;
2415+ const primarySubtreeTag = fiber . subtreeTag & PassiveSubtreeTag ;
2416+ if ( primaryEffectTag === NoEffect && primarySubtreeTag === NoSubtreeTag ) {
2417+ fiber . deletions = null ;
2418+ }
24182419 }
24192420
24202421 if ( fiber . child !== null ) {
@@ -2548,7 +2549,13 @@ function commitMutationEffectsDeletions(
25482549 captureCommitPhaseError ( childToDelete , error ) ;
25492550 }
25502551 }
2551- // Don't clear the Deletion effect yet; we also use it to know when we need to detach refs later.
2552+
2553+ // If there are no pending passive effects, it's safe to detach remaining pointers now.
2554+ const primarySubtreeTag = childToDelete . subtreeTag & PassiveSubtreeTag ;
2555+ const primaryEffectTag = childToDelete . effectTag & PassiveMask ;
2556+ if ( primarySubtreeTag === NoSubtreeTag && primaryEffectTag === NoEffect ) {
2557+ detachFiberAfterEffects ( childToDelete ) ;
2558+ }
25522559 }
25532560}
25542561
@@ -2777,15 +2784,21 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
27772784 for ( let i = 0 ; i < deletions . length ; i ++ ) {
27782785 const fiberToDelete = deletions [ i ] ;
27792786 // If this fiber (or anything below it) has passive effects then traverse the subtree.
2780- const primaryEffectTag = fiberToDelete . effectTag & ( Passive | Update ) ;
2787+ const primaryEffectTag = fiberToDelete . effectTag & PassiveMask ;
27812788 const primarySubtreeTag = fiberToDelete . subtreeTag & PassiveSubtreeTag ;
27822789 if (
27832790 primarySubtreeTag !== NoSubtreeTag ||
27842791 primaryEffectTag !== NoEffect
27852792 ) {
27862793 flushPassiveUnmountEffects ( fiberToDelete ) ;
27872794 }
2795+
2796+ // Now that passive effects have been processed, it's safe to detach lingering pointers.
2797+ detachFiberAfterEffects ( fiberToDelete ) ;
27882798 }
2799+
2800+ // Clear deletions now that passive effects have been procssed.
2801+ fiber . deletions = null ;
27892802 }
27902803
27912804 const didBailout =
@@ -2809,7 +2822,7 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
28092822 case ForwardRef :
28102823 case SimpleMemoComponent :
28112824 case Block : {
2812- const primaryEffectTag = fiber . effectTag & ( Passive | Update ) ;
2825+ const primaryEffectTag = fiber . effectTag & PassiveMask ;
28132826 if ( primaryEffectTag !== NoEffect ) {
28142827 flushPassiveUnmountEffectsImpl ( fiber ) ;
28152828 }
@@ -2934,8 +2947,6 @@ function flushPassiveEffectsImpl() {
29342947 flushPassiveUnmountEffects ( root . current ) ;
29352948 flushPassiveMountEffects ( root . current ) ;
29362949
2937- // TODO (effects) Detach sibling pointers for deleted Fibers
2938-
29392950 if ( enableProfilerTimer && enableProfilerCommitHooks ) {
29402951 const profilerEffects = pendingPassiveProfilerEffects ;
29412952 pendingPassiveProfilerEffects = [ ] ;
@@ -4034,3 +4045,9 @@ export function act(callback: () => Thenable<mixed>): Thenable<void> {
40344045 } ;
40354046 }
40364047}
4048+
4049+ function detachFiberAfterEffects ( fiber : Fiber ) : void {
4050+ fiber . child = null ;
4051+ fiber . sibling = null ;
4052+ fiber . updateQueue = null ;
4053+ }
0 commit comments