Skip to content

Commit 7d618ed

Browse files
author
Brian Vaughn
committed
Defer Fiber field clenaup to passive phase for all but return pointer
1 parent 0c59d06 commit 7d618ed

File tree

2 files changed

+25
-22
lines changed

2 files changed

+25
-22
lines changed

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

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,30 +1015,19 @@ function commitNestedUnmounts(
10151015
}
10161016

10171017
function detachFiberMutation(fiber: Fiber) {
1018-
// Cut off the return pointers to disconnect it from the tree.
1019-
// Note that we can't clear child or sibling pointers yet,
1020-
// because they may be required for passive effects.
1021-
// These pointers will be cleared in a separate pass.
1022-
// Ideally, we should clear the child pointer of the parent alternate to let this
1018+
// Cut off the return pointer to disconnect it from the tree.
1019+
// This enables us to detect and warn against state updates on an unmounted component.
1020+
// It also prevents events from bubbling from within disconnected components.
1021+
//
1022+
// Ideally, we should also clear the child pointer of the parent alternate to let this
10231023
// get GC:ed but we don't know which for sure which parent is the current
1024-
// one so we'll settle for GC:ing the subtree of this child. This child
1025-
// itself will be GC:ed when the parent updates the next time.
1026-
// Note: we cannot null out sibling here, otherwise it can cause issues
1027-
// with findDOMNode and how it requires the sibling field to carry out
1028-
// traversal in a later effect. See PR #16820. We now clear the sibling
1029-
// field after effects, see: detachFiberAfterEffects.
1030-
fiber.alternate = null;
1031-
fiber.dependencies = null;
1032-
fiber.firstEffect = null;
1033-
fiber.lastEffect = null;
1034-
fiber.memoizedProps = null;
1035-
fiber.memoizedState = null;
1036-
fiber.pendingProps = null;
1024+
// one so we'll settle for GC:ing the subtree of this child.
1025+
// This child itself will be GC:ed when the parent updates the next time.
1026+
//
1027+
// Note that we can't clear child or sibling pointers yet.
1028+
// They're needed for passive effects and for findDOMNode.
1029+
// We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
10371030
fiber.return = null;
1038-
fiber.stateNode = null;
1039-
if (__DEV__) {
1040-
fiber._debugOwner = null;
1041-
}
10421031
}
10431032

10441033
function emptyPortalContainer(current: Fiber) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4060,7 +4060,21 @@ export function act(callback: () => Thenable<mixed>): Thenable<void> {
40604060
}
40614061

40624062
function detachFiberAfterEffects(fiber: Fiber): void {
4063+
// Null out fields to improve GC for references that may be lingering (e.g. DevTools).
4064+
// Note that we already cleared the return pointer in detachFiberMutation().
4065+
fiber.alternate = null;
40634066
fiber.child = null;
4067+
fiber.dependencies = null;
4068+
fiber.firstEffect = null;
4069+
fiber.lastEffect = null;
4070+
fiber.memoizedProps = null;
4071+
fiber.memoizedState = null;
4072+
fiber.pendingProps = null;
40644073
fiber.sibling = null;
4074+
fiber.stateNode = null;
40654075
fiber.updateQueue = null;
4076+
4077+
if (__DEV__) {
4078+
fiber._debugOwner = null;
4079+
}
40664080
}

0 commit comments

Comments
 (0)