diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js index f4150c75570fc..664b65bf7d7a8 100644 --- a/packages/react-devtools-shared/src/devtools/store.js +++ b/packages/react-devtools-shared/src/devtools/store.js @@ -1206,6 +1206,14 @@ export default class Store extends EventEmitter<{ } set.add(id); } + + const suspense = this._idToSuspense.get(id); + if (suspense !== undefined) { + // We're reconnecting a node. + if (suspense.name === null) { + suspense.name = this._guessSuspenseName(element); + } + } } break; } @@ -1432,21 +1440,12 @@ export default class Store extends EventEmitter<{ const element = this._idToElement.get(id); if (element === undefined) { - this._throwAndEmitError( - Error( - `Cannot add suspense node "${id}" because no matching element was found in the Store.`, - ), - ); + // This element isn't connected yet. } else { if (name === null) { // The boundary isn't explicitly named. // Pick a sensible default. - // TODO: Use key - const owner = this._idToElement.get(element.ownerID); - if (owner !== undefined) { - // TODO: This is clowny - name = `${owner.displayName || 'Unknown'}>?`; - } + name = this._guessSuspenseName(element); } } @@ -1936,4 +1935,15 @@ export default class Store extends EventEmitter<{ // and for unit testing the Store itself. throw error; } + + _guessSuspenseName(element: Element): string | null { + // TODO: Use key + const owner = this._idToElement.get(element.ownerID); + if (owner !== undefined) { + // TODO: This is clowny + return `${owner.displayName || 'Unknown'}>?`; + } + + return null; + } } diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js index 8f1d1cd7586a9..e7b7052057257 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js @@ -34,6 +34,8 @@ export type Props = {}; // TODO Make edits and deletes also use transition API! +const noSourcePromise = Promise.resolve(null); + export default function InspectedElementWrapper(_: Props): React.Node { const {inspectedElementID} = useContext(TreeStateContext); const bridge = useContext(BridgeContext); @@ -59,11 +61,11 @@ export default function InspectedElementWrapper(_: Props): React.Node { ? inspectedElement.stack[0] : null; - const symbolicatedSourcePromise: null | Promise = + const symbolicatedSourcePromise: Promise = React.useMemo(() => { - if (fetchFileWithCaching == null) return Promise.resolve(null); + if (fetchFileWithCaching == null) return noSourcePromise; - if (source == null) return Promise.resolve(null); + if (source == null) return noSourcePromise; const [, sourceURL, line, column] = source; return symbolicateSourceWithCache( @@ -291,7 +293,7 @@ export default function InspectedElementWrapper(_: Props): React.Node {
Loading...
)} - {inspectedElement !== null && symbolicatedSourcePromise != null && ( + {inspectedElement !== null && (