From dd2acf447bbb54ab5f31a9c3441c85e3675a1a09 Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Mon, 10 Nov 2025 20:19:57 +0100 Subject: [PATCH 1/2] Current behavior --- .../src/__tests__/store-test.js | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index 9b2b2ae54ffd..ce75aa9d4716 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -3298,4 +3298,100 @@ describe('Store', () => { `); }); + + // @reactVersion >= 19.0 + it('measures rects when reconnecting', async () => { + function Component({children, promise}) { + let content = ''; + if (promise) { + const value = readValue(promise); + if (typeof value === 'string') { + content += value; + } + } + return ( +
+ {content} + {children} +
+ ); + } + + function App({outer, inner}) { + return ( + loading outer}> + + outer content + + loading inner + }> + + inner content + + + + ); + } + + await actAsync(() => { + render(); + }); + + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + ▾ + + [suspense-root] rects={[{x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}]} + + + `); + + let outerResolve; + const outerPromise = new Promise(resolve => { + outerResolve = resolve; + }); + + let innerResolve; + const innerPromise = new Promise(resolve => { + innerResolve = resolve; + }); + await actAsync(() => { + render(); + }); + + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + [suspense-root] rects={[{x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}]} + + + `); + + await actAsync(() => { + outerResolve('..'); + innerResolve('.'); + }); + + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + ▾ + + [suspense-root] rects={[{x:1,y:2,width:15,height:1}, {x:1,y:2,width:14,height:1}]} + + + `); + }); }); From 273e94d1046b788bfd1041a87550daa0500d5e15 Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Mon, 10 Nov 2025 20:28:24 +0100 Subject: [PATCH 2/2] [DevTools] Measure when reconnecting Suspense --- .../react-devtools-shared/src/__tests__/store-test.js | 2 +- .../src/backend/fiber/renderer.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index ce75aa9d4716..37272ea0579e 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -3391,7 +3391,7 @@ describe('Store', () => { [suspense-root] rects={[{x:1,y:2,width:15,height:1}, {x:1,y:2,width:14,height:1}]} - + `); }); }); diff --git a/packages/react-devtools-shared/src/backend/fiber/renderer.js b/packages/react-devtools-shared/src/backend/fiber/renderer.js index 2cd037f78d47..8b7e20dcf09f 100644 --- a/packages/react-devtools-shared/src/backend/fiber/renderer.js +++ b/packages/react-devtools-shared/src/backend/fiber/renderer.js @@ -2586,6 +2586,17 @@ export function attach( } } } else { + const suspenseNode = fiberInstance.suspenseNode; + if (suspenseNode !== null && fiber.memoizedState === null) { + // We're reconnecting an unsuspended Suspense. Measure to see if anything changed. + const prevRects = suspenseNode.rects; + const nextRects = measureInstance(fiberInstance); + if (!areEqualRects(prevRects, nextRects)) { + suspenseNode.rects = nextRects; + recordSuspenseResize(suspenseNode); + } + } + const {key} = fiber; const displayName = getDisplayNameForFiber(fiber); const elementType = getElementTypeForFiber(fiber);