@@ -1069,30 +1069,42 @@ function commitNestedUnmounts(
10691069}
10701070
10711071function detachFiberMutation ( fiber : Fiber ) {
1072- // Cut off the return pointers to disconnect it from the tree. Ideally, we
1073- // should clear the child pointer of the parent alternate to let this
1072+ // Cut off the return pointer to disconnect it from the tree.
1073+ // This enables us to detect and warn against state updates on an unmounted component.
1074+ // It also prevents events from bubbling from within disconnected components.
1075+ //
1076+ // Ideally, we should also clear the child pointer of the parent alternate to let this
10741077 // get GC:ed but we don't know which for sure which parent is the current
1075- // one so we'll settle for GC:ing the subtree of this child. This child
1076- // itself will be GC:ed when the parent updates the next time.
1077- // Note: we cannot null out sibling here, otherwise it can cause issues
1078- // with findDOMNode and how it requires the sibling field to carry out
1079- // traversal in a later effect. See PR #16820. We now clear the sibling
1080- // field after effects, see: detachFiberAfterEffects.
1078+ // one so we'll settle for GC:ing the subtree of this child.
1079+ // This child itself will be GC:ed when the parent updates the next time.
10811080 //
1082- // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects.
1083- // It may be required if the current component is an error boundary,
1084- // and one of its descendants throws while unmounting a passive effect.
1085- fiber . alternate = null ;
1081+ // Note that we can't clear child or sibling pointers yet.
1082+ // They're needed for passive effects and for findDOMNode.
1083+ // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
1084+ const alternate = fiber . alternate ;
1085+ if ( alternate !== null ) {
1086+ alternate . return = null ;
1087+ fiber . alternate = null ;
1088+ }
1089+ fiber . return = null ;
1090+ }
1091+
1092+ export function detachFiberAfterEffects ( fiber : Fiber ) : void {
1093+ // Null out fields to improve GC for references that may be lingering (e.g. DevTools).
1094+ // Note that we already cleared the return pointer in detachFiberMutation().
10861095 fiber . child = null ;
10871096 fiber . deletions = null ;
10881097 fiber . dependencies = null ;
1089- fiber . firstEffect = null ;
1090- fiber . lastEffect = null ;
10911098 fiber . memoizedProps = null ;
10921099 fiber . memoizedState = null ;
10931100 fiber . pendingProps = null ;
1094- fiber . return = null ;
1101+ fiber . sibling = null ;
1102+ fiber . stateNode = null ;
10951103 fiber . updateQueue = null ;
1104+ fiber . nextEffect = null ;
1105+ fiber . firstEffect = null ;
1106+ fiber . lastEffect = null ;
1107+
10961108 if ( __DEV__ ) {
10971109 fiber . _debugOwner = null ;
10981110 }
0 commit comments