diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js
index c02d8130c308e..07e8204049752 100644
--- a/packages/react-devtools-shared/src/__tests__/store-test.js
+++ b/packages/react-devtools-shared/src/__tests__/store-test.js
@@ -3243,4 +3243,61 @@ describe('Store', () => {
`);
});
+
+ // @reactVersion >= 19.0
+ it('guesses a Suspense name based on the owner', async () => {
+ let resolve;
+ const promise = new Promise(_resolve => {
+ resolve = _resolve;
+ });
+ function Inner() {
+ return (
+ Loading inner
}>
+ {promise}
+
+ );
+ }
+
+ function Outer({children}) {
+ return (
+ Loading outer}>
+ {promise}
+ {children}
+
+ );
+ }
+
+ await actAsync(() => {
+ render(
+
+
+ ,
+ );
+ });
+
+ expect(store).toMatchInlineSnapshot(`
+ [root]
+ ▾
+
+ [suspense-root] rects={[{x:1,y:2,width:13,height:1}]}
+
+ `);
+
+ console.log('...........................');
+
+ await actAsync(() => {
+ resolve('loaded');
+ });
+
+ expect(store).toMatchInlineSnapshot(`
+ [root]
+ ▾
+ ▾
+ ▾
+
+ [suspense-root] rects={[{x:1,y:2,width:6,height:1}, {x:1,y:2,width:6,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 de178909b29ad..4dd4a619cb4db 100644
--- a/packages/react-devtools-shared/src/backend/fiber/renderer.js
+++ b/packages/react-devtools-shared/src/backend/fiber/renderer.js
@@ -2664,7 +2664,7 @@ export function attach(
const fiber = fiberInstance.data;
const props = fiber.memoizedProps;
- // TODO: Compute a fallback name based on Owner, key etc.
+ // The frontend will guess a name based on heuristics (e.g. owner) if no explicit name is given.
const name =
fiber.tag !== SuspenseComponent || props === null
? null
diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js
index b75e30d9c47ec..aaf0584a4c51a 100644
--- a/packages/react-devtools-shared/src/devtools/store.js
+++ b/packages/react-devtools-shared/src/devtools/store.js
@@ -1646,10 +1646,6 @@ export default class Store extends EventEmitter<{
parentSuspense.children.push(id);
}
- if (name === null) {
- name = 'Unknown';
- }
-
this._idToSuspense.set(id, {
id,
parentID,
@@ -2170,13 +2166,12 @@ export default class Store extends EventEmitter<{
throw error;
}
- _guessSuspenseName(element: Element): string {
+ _guessSuspenseName(element: Element): string | null {
const owner = this._idToElement.get(element.ownerID);
- let name = 'Unknown';
if (owner !== undefined && owner.displayName !== null) {
- name = owner.displayName;
+ return owner.displayName;
}
- return name;
+ return null;
}
}
diff --git a/packages/react-devtools-shared/src/devtools/utils.js b/packages/react-devtools-shared/src/devtools/utils.js
index d5078679f44f9..640f0d19b5797 100644
--- a/packages/react-devtools-shared/src/devtools/utils.js
+++ b/packages/react-devtools-shared/src/devtools/utils.js
@@ -63,11 +63,7 @@ function printRects(rects: SuspenseNode['rects']): string {
}
function printSuspense(suspense: SuspenseNode): string {
- let name = '';
- if (suspense.name !== null) {
- name = ` name="${suspense.name}"`;
- }
-
+ const name = ` name="${suspense.name || 'Unknown'}"`;
const printedRects = printRects(suspense.rects);
return ``;
diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js
index d7112ec7d3a60..b27e0f5987565 100644
--- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js
+++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js
@@ -72,7 +72,7 @@ export default function SuspenseBreadcrumbs(): React$Node {
className={styles.SuspenseBreadcrumbsButton}
onClick={handleClick.bind(null, id)}
type="button">
- {node === null ? 'Unknown' : node.name}
+ {node === null ? 'Unknown' : node.name || 'Unknown'}
);
diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js
index e6beca7c22973..67a6bf277398c 100644
--- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js
+++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js
@@ -196,7 +196,7 @@ function SuspenseRects({
onPointerOver={handlePointerOver}
onPointerLeave={handlePointerLeave}
// Reach-UI tooltip will go out of bounds of parent scroll container.
- title={suspense.name}
+ title={suspense.name || 'Unknown'}
/>
);
})}