Skip to content

Commit ce4054e

Browse files
authored
[DevTools] Measure when reconnecting Suspense (#35098)
1 parent 21c1d51 commit ce4054e

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

packages/react-devtools-shared/src/__tests__/store-test.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,4 +3298,100 @@ describe('Store', () => {
32983298
<Suspense name="Inner" rects={[{x:1,y:2,width:6,height:1}]}>
32993299
`);
33003300
});
3301+
3302+
// @reactVersion >= 19.0
3303+
it('measures rects when reconnecting', async () => {
3304+
function Component({children, promise}) {
3305+
let content = '';
3306+
if (promise) {
3307+
const value = readValue(promise);
3308+
if (typeof value === 'string') {
3309+
content += value;
3310+
}
3311+
}
3312+
return (
3313+
<div>
3314+
{content}
3315+
{children}
3316+
</div>
3317+
);
3318+
}
3319+
3320+
function App({outer, inner}) {
3321+
return (
3322+
<React.Suspense
3323+
name="outer"
3324+
fallback={<Component key="outer-fallback">loading outer</Component>}>
3325+
<Component key="outer-content" promise={outer}>
3326+
outer content
3327+
</Component>
3328+
<React.Suspense
3329+
name="inner"
3330+
fallback={
3331+
<Component key="inner-fallback">loading inner</Component>
3332+
}>
3333+
<Component key="inner-content" promise={inner}>
3334+
inner content
3335+
</Component>
3336+
</React.Suspense>
3337+
</React.Suspense>
3338+
);
3339+
}
3340+
3341+
await actAsync(() => {
3342+
render(<App outer={null} inner={null} />);
3343+
});
3344+
3345+
expect(store).toMatchInlineSnapshot(`
3346+
[root]
3347+
▾ <App>
3348+
▾ <Suspense name="outer">
3349+
<Component key="outer-content">
3350+
▾ <Suspense name="inner">
3351+
<Component key="inner-content">
3352+
[suspense-root] rects={[{x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}]}
3353+
<Suspense name="outer" rects={[{x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}]}>
3354+
<Suspense name="inner" rects={[{x:1,y:2,width:13,height:1}]}>
3355+
`);
3356+
3357+
let outerResolve;
3358+
const outerPromise = new Promise(resolve => {
3359+
outerResolve = resolve;
3360+
});
3361+
3362+
let innerResolve;
3363+
const innerPromise = new Promise(resolve => {
3364+
innerResolve = resolve;
3365+
});
3366+
await actAsync(() => {
3367+
render(<App outer={outerPromise} inner={innerPromise} />);
3368+
});
3369+
3370+
expect(store).toMatchInlineSnapshot(`
3371+
[root]
3372+
▾ <App>
3373+
▾ <Suspense name="outer">
3374+
<Component key="outer-fallback">
3375+
[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}]}
3376+
<Suspense name="outer" rects={[{x:1,y:2,width:13,height:1}, {x:1,y:2,width:13,height:1}]}>
3377+
<Suspense name="inner" rects={[{x:1,y:2,width:13,height:1}]}>
3378+
`);
3379+
3380+
await actAsync(() => {
3381+
outerResolve('..');
3382+
innerResolve('.');
3383+
});
3384+
3385+
expect(store).toMatchInlineSnapshot(`
3386+
[root]
3387+
▾ <App>
3388+
▾ <Suspense name="outer">
3389+
<Component key="outer-content">
3390+
▾ <Suspense name="inner">
3391+
<Component key="inner-content">
3392+
[suspense-root] rects={[{x:1,y:2,width:15,height:1}, {x:1,y:2,width:14,height:1}]}
3393+
<Suspense name="outer" rects={[{x:1,y:2,width:15,height:1}, {x:1,y:2,width:14,height:1}]}>
3394+
<Suspense name="inner" rects={[{x:1,y:2,width:14,height:1}]}>
3395+
`);
3396+
});
33013397
});

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,17 @@ export function attach(
25862586
}
25872587
}
25882588
} else {
2589+
const suspenseNode = fiberInstance.suspenseNode;
2590+
if (suspenseNode !== null && fiber.memoizedState === null) {
2591+
// We're reconnecting an unsuspended Suspense. Measure to see if anything changed.
2592+
const prevRects = suspenseNode.rects;
2593+
const nextRects = measureInstance(fiberInstance);
2594+
if (!areEqualRects(prevRects, nextRects)) {
2595+
suspenseNode.rects = nextRects;
2596+
recordSuspenseResize(suspenseNode);
2597+
}
2598+
}
2599+
25892600
const {key} = fiber;
25902601
const displayName = getDisplayNameForFiber(fiber);
25912602
const elementType = getElementTypeForFiber(fiber);

0 commit comments

Comments
 (0)