Clear fiber.sibling field when clearing nextEffect (#18970)
* Clear fiber.sibling field when clearing nextEffect
Dominic Gannaway committed
May 21, 2020 at 18:53 UTC
730ae7afa2a2f620a77490ad4e2fbcc98f326da2
4 files changed
+30
-8
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+5
-4
@@ -1124,7 +1124,7 @@ function commitNestedUnmounts(
1124
}
1125
}
1126
1127
-function detachFiber(fiber: Fiber) {
1127
+function detachFiberMutation(fiber: Fiber) {
1128
// Cut off the return pointers to disconnect it from the tree. Ideally, we
1129
// should clear the child pointer of the parent alternate to let this
1130
// get GC:ed but we don't know which for sure which parent is the current
@@ -1132,7 +1132,8 @@ function detachFiber(fiber: Fiber) {
1132
// itself will be GC:ed when the parent updates the next time.
1133
// Note: we cannot null out sibling here, otherwise it can cause issues
1134
// with findDOMNode and how it requires the sibling field to carry out
1135
- // traversal in a later effect. See PR #16820.
1135
+ // traversal in a later effect. See PR #16820. We now clear the sibling
1136
+ // field after effects, see: detachFiberAfterEffects.
1137
fiber.alternate = null;
1138
fiber.child = null;
1139
fiber.dependencies_new = null;
@@ -1543,9 +1544,9 @@ function commitDeletion(
1544
commitNestedUnmounts(finishedRoot, current, renderPriorityLevel);
1545
}
1546
const alternate = current.alternate;
1546
- detachFiber(current);
1547
+ detachFiberMutation(current);
1548
if (alternate !== null) {
1548
- detachFiber(alternate);
1549
+ detachFiberMutation(alternate);
1550
}
1551
}
1552
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+5
-4
@@ -1122,7 +1122,7 @@ function commitNestedUnmounts(
1122
}
1123
}
1124
1125
-function detachFiber(fiber: Fiber) {
1125
+function detachFiberMutation(fiber: Fiber) {
1126
// Cut off the return pointers to disconnect it from the tree. Ideally, we
1127
// should clear the child pointer of the parent alternate to let this
1128
// get GC:ed but we don't know which for sure which parent is the current
@@ -1130,7 +1130,8 @@ function detachFiber(fiber: Fiber) {
1130
// itself will be GC:ed when the parent updates the next time.
1131
// Note: we cannot null out sibling here, otherwise it can cause issues
1132
// with findDOMNode and how it requires the sibling field to carry out
1133
- // traversal in a later effect. See PR #16820.
1133
+ // traversal in a later effect. See PR #16820. We now clear the sibling
1134
+ // field after effects, see: detachFiberAfterEffects.
1135
fiber.alternate = null;
1136
fiber.child = null;
1137
fiber.dependencies_old = null;
@@ -1541,9 +1542,9 @@ function commitDeletion(
1542
commitNestedUnmounts(finishedRoot, current, renderPriorityLevel);
1543
}
1544
const alternate = current.alternate;
1544
- detachFiber(current);
1545
+ detachFiberMutation(current);
1546
if (alternate !== null) {
1546
- detachFiber(alternate);
1547
+ detachFiberMutation(alternate);
1548
}
1549
}
1550
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+10
@@ -1993,6 +1993,9 @@ function commitRootImpl(root, renderPriorityLevel) {
1993
while (nextEffect !== null) {
1994
const nextNextEffect = nextEffect.nextEffect;
1995
nextEffect.nextEffect = null;
1996
+ if (nextEffect.effectTag & Deletion) {
1997
+ detachFiberAfterEffects(nextEffect);
1998
+ }
1999
nextEffect = nextNextEffect;
2000
}
2001
}
@@ -2447,6 +2450,9 @@ function flushPassiveEffectsImpl() {
2450
const nextNextEffect = effect.nextEffect;
2451
// Remove nextEffect pointer to assist GC
2452
effect.nextEffect = null;
2453
+ if (effect.effectTag & Deletion) {
2454
+ detachFiberAfterEffects(effect);
2455
+ }
2456
effect = nextNextEffect;
2457
}
2458
@@ -3549,3 +3555,7 @@ export function act(callback: () => Thenable<mixed>): Thenable<void> {
3555
};
3556
}
3557
}
3558
+
3559
+function detachFiberAfterEffects(fiber: Fiber): void {
3560
+ fiber.sibling = null;
3561
+}
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+10
@@ -2101,6 +2101,9 @@ function commitRootImpl(root, renderPriorityLevel) {
2101
while (nextEffect !== null) {
2102
const nextNextEffect = nextEffect.nextEffect;
2103
nextEffect.nextEffect = null;
2104
+ if (nextEffect.effectTag & Deletion) {
2105
+ detachFiberAfterEffects(nextEffect);
2106
+ }
2107
nextEffect = nextNextEffect;
2108
}
2109
}
@@ -2595,6 +2598,9 @@ function flushPassiveEffectsImpl() {
2598
const nextNextEffect = effect.nextEffect;
2599
// Remove nextEffect pointer to assist GC
2600
effect.nextEffect = null;
2601
+ if (effect.effectTag & Deletion) {
2602
+ detachFiberAfterEffects(effect);
2603
+ }
2604
effect = nextNextEffect;
2605
}
2606
@@ -3712,3 +3718,7 @@ export function act(callback: () => Thenable<mixed>): Thenable<void> {
3718
};
3719
}
3720
}
3721
+
3722
+function detachFiberAfterEffects(fiber: Fiber): void {
3723
+ fiber.sibling = null;
3724
+}