@samitouri / QOS-React / commits / 0123d7c19f

[DevTools] Track root instances in a root Map (#30875)

The FiberRoot is a stateful node that can be tracked this way. This is another step that will let us remove the `fiberToFiberInstanceMap`.

Sebastian Markbåge committed Sep 4, 2024 at 16:15 UTC 0123d7c19f2d2b05d612e9bd912b3614024b2aab
1 file changed +35 -22
packages/react-devtools-shared/src/backend/fiber/renderer.js
+35 -22
@@ -114,7 +114,7 @@ import {getStyleXData} from '../StyleX/utils';
114 import {createProfilingHooks} from '../profilingHooks';
115
116 import type {GetTimelineData, ToggleProfilingStatus} from '../profilingHooks';
117 -import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
117 +import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
118 import type {
119 ChangeDescription,
120 CommitDataBackend,
@@ -727,6 +727,9 @@ export function getInternalReactConstants(version: string): {
727 // filters at the same time as removing some other filter.
728 const knownEnvironmentNames: Set<string> = new Set();
729
730 +// Map of FiberRoot to their root FiberInstance.
731 +const rootToFiberInstanceMap: Map<FiberRoot, FiberInstance> = new Map();
732 +
733 // Map of one or more Fibers in a pair to their unique id number.
734 // We track both Fibers to support Fast Refresh,
735 // which may forcefully replace one of the pair as part of hot reloading.
@@ -1243,9 +1246,15 @@ export function attach(
1246
1247 // Recursively unmount all roots.
1248 hook.getFiberRoots(rendererID).forEach(root => {
1246 - const rootInstance = getFiberInstanceThrows(root.current);
1249 + const rootInstance = rootToFiberInstanceMap.get(root);
1250 + if (rootInstance === undefined) {
1251 + throw new Error(
1252 + 'Expected the root instance to already exist when applying filters',
1253 + );
1254 + }
1255 currentRootID = rootInstance.id;
1256 unmountInstanceRecursively(rootInstance);
1257 + rootToFiberInstanceMap.delete(root);
1258 flushPendingEvents(root);
1259 currentRootID = -1;
1260 });
@@ -1260,6 +1269,7 @@ export function attach(
1269 const current = root.current;
1270 const alternate = current.alternate;
1271 const newRoot = createFiberInstance(current);
1272 + rootToFiberInstanceMap.set(root, newRoot);
1273 idToDevToolsInstanceMap.set(newRoot.id, newRoot);
1274 fiberToFiberInstanceMap.set(current, newRoot);
1275 if (alternate) {
@@ -1479,17 +1489,6 @@ export function attach(
1489 // When a mount or update is in progress, this value tracks the root that is being operated on.
1490 let currentRootID: number = -1;
1491
1482 - // Returns a FiberInstance if one has already been generated for the Fiber or throws.
1483 - function getFiberInstanceThrows(fiber: Fiber): FiberInstance {
1484 - const fiberInstance = getFiberInstanceUnsafe(fiber);
1485 - if (fiberInstance !== null) {
1486 - return fiberInstance;
1487 - }
1488 - throw Error(
1489 - `Could not find ID for Fiber "${getDisplayNameForFiber(fiber) || ''}"`,
1490 - );
1491 - }
1492 -
1492 function getFiberIDThrows(fiber: Fiber): number {
1493 const fiberInstance = getFiberInstanceUnsafe(fiber);
1494 if (fiberInstance !== null) {
@@ -2181,7 +2180,7 @@ export function attach(
2180 const isRoot = fiber.tag === HostRoot;
2181 let fiberInstance;
2182 if (isRoot) {
2184 - const entry = fiberToFiberInstanceMap.get(fiber);
2183 + const entry = rootToFiberInstanceMap.get(fiber.stateNode);
2184 if (entry === undefined) {
2185 throw new Error('The root should have been registered at this point');
2186 }
@@ -3591,6 +3590,7 @@ export function attach(
3590 const current = root.current;
3591 const alternate = current.alternate;
3592 const newRoot = createFiberInstance(current);
3593 + rootToFiberInstanceMap.set(root, newRoot);
3594 idToDevToolsInstanceMap.set(newRoot.id, newRoot);
3595 fiberToFiberInstanceMap.set(current, newRoot);
3596 if (alternate) {
@@ -3657,15 +3657,17 @@ export function attach(
3657 }
3658 }
3659
3660 - function handleCommitFiberRoot(root: any, priorityLevel: void | number) {
3660 + function handleCommitFiberRoot(
3661 + root: FiberRoot,
3662 + priorityLevel: void | number,
3663 + ) {
3664 const current = root.current;
3665 const alternate = current.alternate;
3666
3664 - let rootInstance =
3665 - fiberToFiberInstanceMap.get(current) ||
3666 - (alternate && fiberToFiberInstanceMap.get(alternate));
3667 + let rootInstance = rootToFiberInstanceMap.get(root);
3668 if (!rootInstance) {
3669 rootInstance = createFiberInstance(current);
3670 + rootToFiberInstanceMap.set(root, rootInstance);
3671 idToDevToolsInstanceMap.set(rootInstance.id, rootInstance);
3672 fiberToFiberInstanceMap.set(current, rootInstance);
3673 if (alternate) {
@@ -3730,8 +3732,9 @@ export function attach(
3732 updateFiberRecursively(rootInstance, current, alternate, false);
3733 } else if (wasMounted && !isMounted) {
3734 // Unmount an existing root.
3733 - removeRootPseudoKey(currentRootID);
3735 unmountInstanceRecursively(rootInstance);
3736 + removeRootPseudoKey(currentRootID);
3737 + rootToFiberInstanceMap.delete(root);
3738 }
3739 } else {
3740 // Mount a new root.
@@ -5248,7 +5251,12 @@ export function attach(
5251 idToContextsMap = new Map();
5252
5253 hook.getFiberRoots(rendererID).forEach(root => {
5251 - const rootInstance = getFiberInstanceThrows(root.current);
5254 + const rootInstance = rootToFiberInstanceMap.get(root);
5255 + if (rootInstance === undefined) {
5256 + throw new Error(
5257 + 'Expected the root instance to already exist when starting profiling',
5258 + );
5259 + }
5260 const rootID = rootInstance.id;
5261 ((displayNamesByRootID: any): DisplayNamesByRootID).set(
5262 rootID,
@@ -5645,8 +5653,13 @@ export function attach(
5653 case HostRoot:
5654 // Roots don't have a real displayName, index, or key.
5655 // Instead, we'll use the pseudo key (childDisplayName:indexWithThatName).
5648 - const id = getFiberIDThrows(fiber);
5649 - const pseudoKey = rootPseudoKeys.get(id);
5656 + const rootInstance = rootToFiberInstanceMap.get(fiber.stateNode);
5657 + if (rootInstance === undefined) {
5658 + throw new Error(
5659 + 'Expected the root instance to exist when computing a path',
5660 + );
5661 + }
5662 + const pseudoKey = rootPseudoKeys.get(rootInstance.id);
5663 if (pseudoKey === undefined) {
5664 throw new Error('Expected mounted root to have known pseudo key.');
5665 }