DevTools should not crawl unmounted subtrees when profiling starts (#23162)

Previously we crawled all subtrees, even not-yet-mounted ones, to initialize context values. This was not only unecessary, but it also caused an error to be thrown. This commit adds a test and fixes that behavior.
This commit is contained in:
Brian Vaughn
2022-01-21 11:05:49 -05:00
committed by GitHub
parent ca143e18d8
commit 13036bfbc8
2 changed files with 33 additions and 5 deletions
@@ -221,4 +221,24 @@ describe('ProfilerStore', () => {
expect(data.commitData).toHaveLength(1);
expect(data.operations).toHaveLength(1);
});
it('should not throw while initializing context values for Fibers within a not-yet-mounted subtree', () => {
const promise = new Promise(resolve => {});
const SuspendingView = () => {
throw promise;
};
const App = () => {
return (
<React.Suspense fallback="Fallback">
<SuspendingView />
</React.Suspense>
);
};
const container = document.createElement('div');
utils.act(() => legacyRender(<App />, container));
utils.act(() => store.profilerStore.startProfiling());
});
});
+13 -5
View File
@@ -1347,11 +1347,19 @@ export function attach(
// Fibers only store the current context value,
// so we need to track them separately in order to determine changed keys.
function crawlToInitializeContextsMap(fiber: Fiber) {
updateContextsForFiber(fiber);
let current = fiber.child;
while (current !== null) {
crawlToInitializeContextsMap(current);
current = current.sibling;
const id = getFiberIDUnsafe(fiber);
// Not all Fibers in the subtree have mounted yet.
// For example, Offscreen (hidden) or Suspense (suspended) subtrees won't yet be tracked.
// We can safely skip these subtrees.
if (id !== null) {
updateContextsForFiber(fiber);
let current = fiber.child;
while (current !== null) {
crawlToInitializeContextsMap(current);
current = current.sibling;
}
}
}