@samitouri / QOS-React / commits / a9ad64c852

[DevTools] Stop mounting empty roots (#34467)

Sebastian "Sebbie" Silbermann committed Sep 11, 2025 at 20:00 UTC a9ad64c8524eb7a9af6753baa715a41909552fa6
2 files changed +24 -26
packages/react-devtools-shared/src/__tests__/store-test.js
+4 -1
@@ -2489,7 +2489,7 @@ describe('Store', () => {
2489 withErrorsOrWarningsIgnored(['test-only:'], async () => {
2490 await act(() => render(<React.Fragment />));
2491 });
2492 - expect(store).toMatchInlineSnapshot(`[root]`);
2492 + expect(store).toMatchInlineSnapshot(``);
2493 expect(store.componentWithErrorCount).toBe(0);
2494 expect(store.componentWithWarningCount).toBe(0);
2495 });
@@ -3083,6 +3083,9 @@ describe('Store', () => {
3083
3084 it('should handle an empty root', async () => {
3085 await actAsync(() => render(null));
3086 + expect(store).toMatchInlineSnapshot(``);
3087 +
3088 + await actAsync(() => render(<span />));
3089 expect(store).toMatchInlineSnapshot(`[root]`);
3090 });
3091 });
packages/react-devtools-shared/src/backend/fiber/renderer.js
+20 -25
@@ -5322,12 +5322,12 @@ export function attach(
5322 root: FiberRoot,
5323 priorityLevel: void | number,
5324 ) {
5325 - const current = root.current;
5325 + const nextFiber = root.current;
5326
5327 let prevFiber: null | Fiber = null;
5328 let rootInstance = rootToFiberInstanceMap.get(root);
5329 if (!rootInstance) {
5330 - rootInstance = createFiberInstance(current);
5330 + rootInstance = createFiberInstance(nextFiber);
5331 rootToFiberInstanceMap.set(root, rootInstance);
5332 idToDevToolsInstanceMap.set(rootInstance.id, rootInstance);
5333 } else {
@@ -5366,30 +5366,25 @@ export function attach(
5366 };
5367 }
5368
5369 - if (prevFiber !== null) {
5370 - // TODO: relying on this seems a bit fishy.
5371 - const wasMounted =
5372 - prevFiber.memoizedState != null &&
5373 - prevFiber.memoizedState.element != null;
5374 - const isMounted =
5375 - current.memoizedState != null && current.memoizedState.element != null;
5376 - if (!wasMounted && isMounted) {
5377 - // Mount a new root.
5378 - setRootPseudoKey(currentRoot.id, current);
5379 - mountFiberRecursively(current, false);
5380 - } else if (wasMounted && isMounted) {
5381 - // Update an existing root.
5382 - updateFiberRecursively(rootInstance, current, prevFiber, false);
5383 - } else if (wasMounted && !isMounted) {
5384 - // Unmount an existing root.
5385 - unmountInstanceRecursively(rootInstance);
5386 - removeRootPseudoKey(currentRoot.id);
5387 - rootToFiberInstanceMap.delete(root);
5388 - }
5389 - } else {
5369 + const nextIsMounted = nextFiber.child !== null;
5370 + const prevWasMounted = prevFiber !== null && prevFiber.child !== null;
5371 + if (!prevWasMounted && nextIsMounted) {
5372 // Mount a new root.
5391 - setRootPseudoKey(currentRoot.id, current);
5392 - mountFiberRecursively(current, false);
5373 + setRootPseudoKey(currentRoot.id, nextFiber);
5374 + mountFiberRecursively(nextFiber, false);
5375 + } else if (prevWasMounted && nextIsMounted) {
5376 + if (prevFiber === null) {
5377 + throw new Error(
5378 + 'Expected a previous Fiber when updating an existing root.',
5379 + );
5380 + }
5381 + // Update an existing root.
5382 + updateFiberRecursively(rootInstance, nextFiber, prevFiber, false);
5383 + } else if (prevWasMounted && !nextIsMounted) {
5384 + // Unmount an existing root.
5385 + unmountInstanceRecursively(rootInstance);
5386 + removeRootPseudoKey(currentRoot.id);
5387 + rootToFiberInstanceMap.delete(root);
5388 }
5389
5390 if (isProfiling && isProfilingSupported) {