Keep track of root insertion order in the renderer
Normally, Fibers have key or index which we'll use to match things up between reloads. However, roots don't have such a concept. We'll use their insertion order as an approximation. If it's consistent, we'll be able to restore the selection.
Dan Abramov committed
Apr 23, 2019 at 15:42 UTC
b1a7007cc5194d769610abf9de796eb152f161b1
1 file changed
+7
src/backend/renderer.js
+7
@@ -539,6 +539,11 @@ export function attach(
539
// When a mount or update is in progress, this value tracks the root that is being operated on.
540
let currentRootID: number = -1;
541
542
+ // Track the order in which roots were added.
543
+ // We will use it to disambiguate roots when restoring selection between reloads.
544
+ let nextRootIndex = 0;
545
+ const rootInsertionOrder: Map<number, number> = new Map();
546
+
547
function getFiberID(primaryFiber: Fiber): number {
548
if (!fiberToIDMap.has(primaryFiber)) {
549
const id = getUID();
@@ -690,6 +695,7 @@ export function attach(
695
const hasOwnerMetadata = fiber.hasOwnProperty('_debugOwner');
696
697
if (isRoot) {
698
+ rootInsertionOrder.set(id, nextRootIndex++);
699
pushOperation(TREE_OPERATION_ADD);
700
pushOperation(id);
701
pushOperation(ElementTypeRoot);
@@ -777,6 +783,7 @@ export function attach(
783
}
784
const id = getFiberID(primaryFiber);
785
if (isRoot) {
786
+ rootInsertionOrder.delete(id);
787
// Removing a root needs to happen at the end
788
// so we don't batch it with other unmounts.
789
pushOperation(TREE_OPERATION_REMOVE);