Traverse the previous current tree when switching from primary to fallback
Dan Abramov committed
Apr 18, 2019 at 16:19 UTC
6a13ffd2314275b9e1ae8eda5acd614d22edc15a
4 files changed
+14
-94
src/backend/renderer.js
+14
-15
@@ -22,7 +22,6 @@ import {
22
TREE_OPERATION_ADD,
23
TREE_OPERATION_REMOVE,
24
TREE_OPERATION_RESET_CHILDREN,
25
- TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
25
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
26
} from '../constants';
27
import { getUID } from '../utils';
@@ -772,15 +771,6 @@ export function attach(
771
}
772
}
773
775
- function recordRecursiveRemoveChildren(fiber) {
776
- const primaryFiber = getPrimaryFiber(fiber);
777
- const id = getFiberID(primaryFiber);
778
- beginNextOperation(2);
779
- nextOperation[0] = TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN;
780
- nextOperation[1] = id;
781
- endNextOperation(false);
782
- }
783
-
774
function mountFiberRecursively(
775
fiber: Fiber,
776
parentFiber: Fiber | null,
@@ -828,6 +818,18 @@ export function attach(
818
}
819
}
820
821
+ function unmountFiberChildrenRecursively(fiber: Fiber) {
822
+ if (__DEBUG__) {
823
+ debug('unmountFiberChildrenRecursively()', fiber);
824
+ }
825
+ let child = fiber.child;
826
+ while (child !== null) {
827
+ recordUnmount(child);
828
+ unmountFiberChildrenRecursively(child);
829
+ child = child.sibling;
830
+ }
831
+ }
832
+
833
function recordTreeDuration(fiber: Fiber) {
834
const id = getFiberID(getPrimaryFiber(fiber));
835
const { actualDuration, treeBaseDuration } = fiber;
@@ -955,11 +957,8 @@ export function attach(
957
// Primary -> Fallback:
958
// 1. Hide primary set
959
// This is not a real unmount, so it won't get reported by React.
958
- // By this point it's *too late* to find the previous primary child set
959
- // so we'll just tell the store to "forget" about those children.
960
- // They might "resurface" later when we switch to primary content,
961
- // but from the store's point of view they will be a new tree.
962
- recordRecursiveRemoveChildren(nextFiber);
960
+ // We need to manually walk the previous tree and record unmounts.
961
+ unmountFiberChildrenRecursively(prevFiber);
962
// 2. Mount fallback set
963
const nextFallbackChildSet = nextFiber.child.sibling;
964
mountFiberRecursively(nextFallbackChildSet, nextFiber, true);
src/constants.js
-1
@@ -4,7 +4,6 @@ export const TREE_OPERATION_ADD = 1;
4
export const TREE_OPERATION_REMOVE = 2;
5
export const TREE_OPERATION_RESET_CHILDREN = 3;
6
export const TREE_OPERATION_UPDATE_TREE_BASE_DURATION = 4;
7
-export const TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN = 5;
7
8
export const LOCAL_STORAGE_RELOAD_AND_PROFILE_KEY =
9
'React::DevTools::reloadAndProfile';
src/devtools/store.js
-46
@@ -5,7 +5,6 @@ import memoize from 'memoize-one';
5
import throttle from 'lodash.throttle';
6
import {
7
TREE_OPERATION_ADD,
8
- TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
8
TREE_OPERATION_REMOVE,
9
TREE_OPERATION_RESET_CHILDREN,
10
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
@@ -695,51 +694,6 @@ export default class Store extends EventEmitter {
694
weightDelta = 1;
695
}
696
break;
698
- case TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN: {
699
- id = ((operations[i + 1]: any): number);
700
-
701
- if (!this._idToElement.has(id)) {
702
- throw new Error(
703
- 'Store does not contain fiber ' +
704
- id +
705
- '. This is a bug in React DevTools.'
706
- );
707
- }
708
-
709
- i = i + 2;
710
-
711
- let justRemovedIDs = [];
712
- const recursivelyRemove = childID => {
713
- justRemovedIDs.push(childID);
714
- const child = this._idToElement.get(childID);
715
- if (!child) {
716
- throw new Error(
717
- 'Store does not contain fiber ' +
718
- childID +
719
- '. This is a bug in React DevTools.'
720
- );
721
- }
722
- this._idToElement.delete(childID);
723
- child.children.forEach(recursivelyRemove);
724
- };
725
-
726
- // Track removed items so search results can be updated
727
- const oldRemovedElementIDs = removedElementIDs;
728
- removedElementIDs = new Uint32Array(
729
- removedElementIDs.length + justRemovedIDs.length
730
- );
731
- removedElementIDs.set(oldRemovedElementIDs);
732
- let startIndex = oldRemovedElementIDs.length;
733
- for (let j = 0; j < justRemovedIDs.length; j++) {
734
- removedElementIDs[startIndex + j] = oldRemovedElementIDs[j];
735
- }
736
-
737
- parentElement = ((this._idToElement.get(id): any): Element);
738
- parentElement.children.forEach(recursivelyRemove);
739
- parentElement.children = [];
740
- weightDelta = -parentElement.weight + 1;
741
- break;
742
- }
697
case TREE_OPERATION_REMOVE: {
698
id = ((operations[i + 1]: any): number);
699
src/devtools/views/Profiler/CommitTreeBuilder.js
-32
@@ -3,7 +3,6 @@
3
import {
4
__DEBUG__,
5
TREE_OPERATION_ADD,
6
- TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
6
TREE_OPERATION_REMOVE,
7
TREE_OPERATION_RESET_CHILDREN,
8
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
@@ -256,37 +255,6 @@ function updateTree(
255
nodes.set(id, node);
256
}
257
break;
259
- case TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN:
260
- id = ((operations[i + 1]: any): number);
261
-
262
- i = i + 2;
263
-
264
- if (!nodes.has(id)) {
265
- throw new Error(
266
- 'Commit tree does not contain fiber ' +
267
- id +
268
- '. This is a bug in React DevTools.'
269
- );
270
- }
271
-
272
- node = getClonedNode(id);
273
-
274
- const recursivelyRemove = childID => {
275
- if (!nodes.has(id)) {
276
- throw new Error(
277
- 'Commit tree does not contain fiber ' +
278
- id +
279
- '. This is a bug in React DevTools.'
280
- );
281
- }
282
- const child = getClonedNode(childID);
283
- nodes.delete(childID);
284
- child.children.forEach(recursivelyRemove);
285
- };
286
-
287
- node.children.forEach(recursivelyRemove);
288
- node.children = [];
289
- break;
258
case TREE_OPERATION_REMOVE:
259
id = ((operations[i + 1]: any): number);
260