Skip to content

Commit 8d557a6

Browse files
authored
[DevTools] Only show Suspense rects matching "unique-suspenders-only" filter (#34607)
1 parent 6a51a9f commit 8d557a6

File tree

3 files changed

+71
-10
lines changed

3 files changed

+71
-10
lines changed

packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
overflow: hidden;
2020
}
2121

22+
.SuspenseRectsScaledRect[data-visible='false'] > .SuspenseRectsBoundaryChildren {
23+
overflow: initial;
24+
}
25+
2226
.SuspenseRectsRect {
2327
box-shadow: var(--elevation-4);
2428
pointer-events: all;
@@ -31,6 +35,11 @@
3135
outline-color: var(--color-background-selected);
3236
}
3337

38+
.SuspenseRectsScaledRect[data-visible='false'] {
39+
pointer-events: none;
40+
outline-width: 0;
41+
}
42+
3443
/* highlight this boundary */
3544
.SuspenseRectsBoundary:hover:not(:has(.SuspenseRectsBoundary:hover)) > .SuspenseRectsRect, .SuspenseRectsBoundary[data-highlighted='true'] > .SuspenseRectsRect {
3645
background-color: var(--color-background-hover);

packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ import {
3434
function ScaledRect({
3535
className,
3636
rect,
37+
visible,
3738
...props
3839
}: {
3940
className: string,
4041
rect: Rect,
42+
visible: boolean,
4143
...
4244
}): React$Node {
4345
const viewBox = useContext(ViewBox);
@@ -50,6 +52,7 @@ function ScaledRect({
5052
<div
5153
{...props}
5254
className={styles.SuspenseRectsScaledRect + ' ' + className}
55+
data-visible={visible}
5356
style={{
5457
width,
5558
height,
@@ -68,6 +71,7 @@ function SuspenseRects({
6871
const store = useContext(StoreContext);
6972
const treeDispatch = useContext(TreeDispatcherContext);
7073
const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext);
74+
const {uniqueSuspendersOnly} = useContext(SuspenseTreeStateContext);
7175

7276
const {inspectedElementID} = useContext(TreeStateContext);
7377

@@ -79,6 +83,7 @@ function SuspenseRects({
7983
// getSuspenseByID will have already warned
8084
return null;
8185
}
86+
const visible = suspense.hasUniqueSuspenders || !uniqueSuspendersOnly;
8287

8388
function handleClick(event: SyntheticMouseEvent) {
8489
if (event.defaultPrevented) {
@@ -117,9 +122,13 @@ function SuspenseRects({
117122
const boundingBox = getBoundingBox(suspense.rects);
118123

119124
return (
120-
<ScaledRect rect={boundingBox} className={styles.SuspenseRectsBoundary}>
125+
<ScaledRect
126+
rect={boundingBox}
127+
className={styles.SuspenseRectsBoundary}
128+
visible={visible}>
121129
<ViewBox.Provider value={boundingBox}>
122-
{suspense.rects !== null &&
130+
{visible &&
131+
suspense.rects !== null &&
123132
suspense.rects.map((rect, index) => {
124133
return (
125134
<ScaledRect
@@ -245,6 +254,7 @@ function SuspenseRectsContainer(): React$Node {
245254
// TODO: This relies on a full re-render of all children when the Suspense tree changes.
246255
const {roots} = useContext(SuspenseTreeStateContext);
247256

257+
// TODO: bbox does not consider uniqueSuspendersOnly filter
248258
const boundingBox = getDocumentBoundingRect(store, roots);
249259

250260
const boundingBoxWidth = boundingBox.width;

packages/react-devtools-shell/src/app/SuspenseTree/index.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,12 @@ function EmptySuspense() {
184184
// $FlowFixMe[missing-local-annot]
185185
function PrimaryFallbackTest({initialSuspend}) {
186186
const [suspend, setSuspend] = useState(initialSuspend);
187-
const fallbackStep = useTestSequence('fallback', Fallback1, Fallback2);
188-
const primaryStep = useTestSequence('primary', Primary1, Primary2);
187+
const [fallbackStepIndex, fallbackStep] = useTestSequence(
188+
'fallback',
189+
Fallback1,
190+
Fallback2,
191+
);
192+
const [, primaryStep] = useTestSequence('primary', Primary1, Primary2);
189193
return (
190194
<Fragment>
191195
<label>
@@ -198,7 +202,11 @@ function PrimaryFallbackTest({initialSuspend}) {
198202
</label>
199203
<br />
200204
<Suspense fallback={fallbackStep}>
201-
{suspend ? <Never /> : primaryStep}
205+
{suspend ? (
206+
<Never id={`primary-fallback-test-${fallbackStepIndex}`} />
207+
) : (
208+
primaryStep
209+
)}
202210
</Suspense>
203211
</Fragment>
204212
);
@@ -227,7 +235,7 @@ function useTestSequence(label: string, T1: any => any, T2: any => any) {
227235
{next} <T2 prop={step}>goodbye</T2>
228236
</Fragment>,
229237
];
230-
return allSteps[step];
238+
return [step, allSteps[step]];
231239
}
232240

233241
function NestedSuspenseTest() {
@@ -252,7 +260,7 @@ function Parent() {
252260
</Suspense>
253261
<br />
254262
<Suspense fallback={<Fallback1>This will never load</Fallback1>}>
255-
<Never />
263+
<Never id="parent-never" />
256264
</Suspense>
257265
<br />
258266
<b>
@@ -298,14 +306,48 @@ function LoadLater() {
298306
Loaded! Click to suspend again.
299307
</Primary1>
300308
) : (
301-
<Never />
309+
<Never id="load-later" />
302310
)}
303311
</Suspense>
304312
);
305313
}
306314

307-
function Never() {
308-
throw new Promise(resolve => {});
315+
function readRecord(promise: any): any {
316+
if (typeof React.use === 'function') {
317+
return React.use(promise);
318+
}
319+
switch (promise.status) {
320+
case 'pending':
321+
throw promise;
322+
case 'rejected':
323+
throw promise.reason;
324+
case 'fulfilled':
325+
return promise.value;
326+
default:
327+
promise.status = 'pending';
328+
promise.then(
329+
value => {
330+
promise.status = 'fulfilled';
331+
promise.value = value;
332+
},
333+
reason => {
334+
promise.status = 'rejected';
335+
promise.reason = reason;
336+
},
337+
);
338+
throw promise;
339+
}
340+
}
341+
342+
const nevers = new Map<string, Promise<empty>>();
343+
function Never({id}: {id: string}) {
344+
let promise = nevers.get(id);
345+
if (!promise) {
346+
promise = new Promise(() => {});
347+
(promise as any).displayName = id;
348+
nevers.set(id, promise);
349+
}
350+
readRecord(promise);
309351
}
310352

311353
function Fallback1({prop, ...rest}: any) {

0 commit comments

Comments
 (0)