Skip to content

Commit 0123d7c

Browse files
authored
[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`.
1 parent e10e868 commit 0123d7c

File tree

1 file changed

+35
-22
lines changed
  • packages/react-devtools-shared/src/backend/fiber

1 file changed

+35
-22
lines changed

packages/react-devtools-shared/src/backend/fiber/renderer.js

+35-22
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ import {getStyleXData} from '../StyleX/utils';
114114
import {createProfilingHooks} from '../profilingHooks';
115115

116116
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';
118118
import type {
119119
ChangeDescription,
120120
CommitDataBackend,
@@ -727,6 +727,9 @@ export function getInternalReactConstants(version: string): {
727727
// filters at the same time as removing some other filter.
728728
const knownEnvironmentNames: Set<string> = new Set();
729729

730+
// Map of FiberRoot to their root FiberInstance.
731+
const rootToFiberInstanceMap: Map<FiberRoot, FiberInstance> = new Map();
732+
730733
// Map of one or more Fibers in a pair to their unique id number.
731734
// We track both Fibers to support Fast Refresh,
732735
// which may forcefully replace one of the pair as part of hot reloading.
@@ -1243,9 +1246,15 @@ export function attach(
12431246

12441247
// Recursively unmount all roots.
12451248
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+
}
12471255
currentRootID = rootInstance.id;
12481256
unmountInstanceRecursively(rootInstance);
1257+
rootToFiberInstanceMap.delete(root);
12491258
flushPendingEvents(root);
12501259
currentRootID = -1;
12511260
});
@@ -1260,6 +1269,7 @@ export function attach(
12601269
const current = root.current;
12611270
const alternate = current.alternate;
12621271
const newRoot = createFiberInstance(current);
1272+
rootToFiberInstanceMap.set(root, newRoot);
12631273
idToDevToolsInstanceMap.set(newRoot.id, newRoot);
12641274
fiberToFiberInstanceMap.set(current, newRoot);
12651275
if (alternate) {
@@ -1479,17 +1489,6 @@ export function attach(
14791489
// When a mount or update is in progress, this value tracks the root that is being operated on.
14801490
let currentRootID: number = -1;
14811491

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-
14931492
function getFiberIDThrows(fiber: Fiber): number {
14941493
const fiberInstance = getFiberInstanceUnsafe(fiber);
14951494
if (fiberInstance !== null) {
@@ -2181,7 +2180,7 @@ export function attach(
21812180
const isRoot = fiber.tag === HostRoot;
21822181
let fiberInstance;
21832182
if (isRoot) {
2184-
const entry = fiberToFiberInstanceMap.get(fiber);
2183+
const entry = rootToFiberInstanceMap.get(fiber.stateNode);
21852184
if (entry === undefined) {
21862185
throw new Error('The root should have been registered at this point');
21872186
}
@@ -3591,6 +3590,7 @@ export function attach(
35913590
const current = root.current;
35923591
const alternate = current.alternate;
35933592
const newRoot = createFiberInstance(current);
3593+
rootToFiberInstanceMap.set(root, newRoot);
35943594
idToDevToolsInstanceMap.set(newRoot.id, newRoot);
35953595
fiberToFiberInstanceMap.set(current, newRoot);
35963596
if (alternate) {
@@ -3657,15 +3657,17 @@ export function attach(
36573657
}
36583658
}
36593659

3660-
function handleCommitFiberRoot(root: any, priorityLevel: void | number) {
3660+
function handleCommitFiberRoot(
3661+
root: FiberRoot,
3662+
priorityLevel: void | number,
3663+
) {
36613664
const current = root.current;
36623665
const alternate = current.alternate;
36633666

3664-
let rootInstance =
3665-
fiberToFiberInstanceMap.get(current) ||
3666-
(alternate && fiberToFiberInstanceMap.get(alternate));
3667+
let rootInstance = rootToFiberInstanceMap.get(root);
36673668
if (!rootInstance) {
36683669
rootInstance = createFiberInstance(current);
3670+
rootToFiberInstanceMap.set(root, rootInstance);
36693671
idToDevToolsInstanceMap.set(rootInstance.id, rootInstance);
36703672
fiberToFiberInstanceMap.set(current, rootInstance);
36713673
if (alternate) {
@@ -3730,8 +3732,9 @@ export function attach(
37303732
updateFiberRecursively(rootInstance, current, alternate, false);
37313733
} else if (wasMounted && !isMounted) {
37323734
// Unmount an existing root.
3733-
removeRootPseudoKey(currentRootID);
37343735
unmountInstanceRecursively(rootInstance);
3736+
removeRootPseudoKey(currentRootID);
3737+
rootToFiberInstanceMap.delete(root);
37353738
}
37363739
} else {
37373740
// Mount a new root.
@@ -5248,7 +5251,12 @@ export function attach(
52485251
idToContextsMap = new Map();
52495252

52505253
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+
}
52525260
const rootID = rootInstance.id;
52535261
((displayNamesByRootID: any): DisplayNamesByRootID).set(
52545262
rootID,
@@ -5645,8 +5653,13 @@ export function attach(
56455653
case HostRoot:
56465654
// Roots don't have a real displayName, index, or key.
56475655
// 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);
56505663
if (pseudoKey === undefined) {
56515664
throw new Error('Expected mounted root to have known pseudo key.');
56525665
}

0 commit comments

Comments
 (0)