@samitouri / QOS-React / commits / 6a13ffd231

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