@samitouri / QOS-React / commits / 2d98b45d92

[DevTools] Fix Suspense boundaries always being marked as not suspended (#34206)

Sebastian "Sebbie" Silbermann committed Aug 15, 2025 at 19:39 UTC 2d98b45d92ee9adc5ec6dbd2a5a270e0fd2607a4
7 files changed +17 -4
packages/react-devtools-shared/src/backend/fiber/renderer.js
+8
@@ -6071,6 +6071,11 @@ export function attach(
6071 nativeTag = getNativeTag(fiber.stateNode);
6072 }
6073
6074 + let isSuspended: boolean | null = null;
6075 + if (tag === SuspenseComponent) {
6076 + isSuspended = memoizedState !== null;
6077 + }
6078 +
6079 const suspendedBy =
6080 fiberInstance.suspenseNode !== null
6081 ? // If this is a Suspense boundary, then we include everything in the subtree that might suspend
@@ -6121,6 +6126,7 @@ export function attach(
6126 forceFallbackForFibers.has(fiber) ||
6127 (fiber.alternate !== null &&
6128 forceFallbackForFibers.has(fiber.alternate))),
6129 + isSuspended: isSuspended,
6130
6131 source,
6132
@@ -6209,6 +6215,7 @@ export function attach(
6215 const componentLogsEntry =
6216 componentInfoToComponentLogsMap.get(componentInfo);
6217
6218 + const isSuspended = null;
6219 // Things that Suspended this Server Component (use(), awaits and direct child promises)
6220 const suspendedBy = virtualInstance.suspendedBy;
6221 const suspendedByRange = getSuspendedByRange(
@@ -6230,6 +6237,7 @@ export function attach(
6237 isErrored: false,
6238
6239 canToggleSuspense: supportsTogglingSuspense && hasSuspenseBoundary,
6240 + isSuspended: isSuspended,
6241
6242 source,
6243
packages/react-devtools-shared/src/backend/legacy/renderer.js
+1
@@ -836,6 +836,7 @@ export function attach(
836
837 // Suspense did not exist in legacy versions
838 canToggleSuspense: false,
839 + isSuspended: null,
840
841 source: null,
842
packages/react-devtools-shared/src/backend/types.js
+2
@@ -285,6 +285,8 @@ export type InspectedElement = {
285
286 // Is this Suspense, and can its value be overridden now?
287 canToggleSuspense: boolean,
288 + // If this Element is suspended. Currently only set on Suspense boundaries.
289 + isSuspended: boolean | null,
290
291 // Does the component have legacy context attached to it.
292 hasLegacyContext: boolean,
packages/react-devtools-shared/src/backendAPI.js
+2
@@ -251,6 +251,7 @@ export function convertInspectedElementBackendToFrontend(
251 canToggleError,
252 isErrored,
253 canToggleSuspense,
254 + isSuspended,
255 hasLegacyContext,
256 id,
257 type,
@@ -287,6 +288,7 @@ export function convertInspectedElementBackendToFrontend(
288 canToggleError,
289 isErrored,
290 canToggleSuspense,
291 + isSuspended,
292 hasLegacyContext,
293 id,
294 key,
packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js
+1 -1
@@ -113,7 +113,7 @@ export default function InspectedElementWrapper(_: Props): React.Node {
113 element !== null &&
114 element.type === ElementTypeSuspense &&
115 inspectedElement != null &&
116 - inspectedElement.state != null;
116 + inspectedElement.isSuspended;
117
118 const canToggleError =
119 !hideToggleErrorAction &&
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspenseToggle.js
+1 -3
@@ -30,15 +30,13 @@ export default function InspectedElementSuspenseToggle({
30 }: Props): React.Node {
31 const {readOnly} = React.useContext(OptionsContext);
32
33 - const {id, state, type} = inspectedElement;
33 + const {id, isSuspended, type} = inspectedElement;
34 const canToggleSuspense = !readOnly && inspectedElement.canToggleSuspense;
35
36 if (type !== ElementTypeSuspense) {
37 return null;
38 }
39
40 - const isSuspended = state !== null;
41 -
40 const toggleSuspense = (path: any, value: boolean) => {
41 const rendererID = store.getRendererIDForElement(id);
42 if (rendererID !== null) {
packages/react-devtools-shared/src/frontend/types.js
+2
@@ -264,6 +264,8 @@ export type InspectedElement = {
264
265 // Is this Suspense, and can its value be overridden now?
266 canToggleSuspense: boolean,
267 + // If this Element is suspended. Currently only set on Suspense boundaries.
268 + isSuspended: boolean | null,
269
270 // Does the component have legacy context attached to it.
271 hasLegacyContext: boolean,