@samitouri / QOS-React / commits / 34ce3acafd

[DevTools] Pick up suspended by info from React.lazy in type position (#34144)

Normally, we pick up debug info from instrumented Promise or React.Lazy while we're reconciling in ReactChildFiber when they appear in the child position. We add those to the `_debugInfo` of the Fiber. However, we don't do that for for Lazy in the Component type position. Instead, we have to pick up the debug info from it explicitly in DevTools. Likely this is the info added by #34137. Older versions wouldn't be covered by this particular mechanism but more generally from throwing a Promise. <img width="592" height="449" alt="Screenshot 2025-08-08 at 11 32 33 PM" src="https://github.com/user-attachments/assets/87211c64-a7df-47b7-a784-5cdc7c5fae16" />

Sebastian Markbåge committed Aug 11, 2025 at 11:42 UTC 34ce3acafdcfb6830250043b64d8af2450c730bc
1 file changed +24
packages/react-devtools-shared/src/backend/fiber/renderer.js
+24
@@ -104,6 +104,7 @@ import {
104 MEMO_NUMBER,
105 MEMO_SYMBOL_STRING,
106 SERVER_CONTEXT_SYMBOL_STRING,
107 + LAZY_SYMBOL_STRING,
108 } from '../shared/ReactSymbols';
109 import {enableStyleXFeatures} from 'react-devtools-feature-flags';
110
@@ -3161,6 +3162,25 @@ export function attach(
3162 return null;
3163 }
3164
3165 + function trackDebugInfoFromLazyType(fiber: Fiber): void {
3166 + // The debugInfo from a Lazy isn't propagated onto _debugInfo of the parent Fiber the way
3167 + // it is when used in child position. So we need to pick it up explicitly.
3168 + const type = fiber.elementType;
3169 + const typeSymbol = getTypeSymbol(type); // The elementType might be have been a LazyComponent.
3170 + if (typeSymbol === LAZY_SYMBOL_STRING) {
3171 + const debugInfo: ?ReactDebugInfo = type._debugInfo;
3172 + if (debugInfo) {
3173 + for (let i = 0; i < debugInfo.length; i++) {
3174 + const debugEntry = debugInfo[i];
3175 + if (debugEntry.awaited) {
3176 + const asyncInfo: ReactAsyncInfo = (debugEntry: any);
3177 + insertSuspendedBy(asyncInfo);
3178 + }
3179 + }
3180 + }
3181 + }
3182 + }
3183 +
3184 function mountVirtualChildrenRecursively(
3185 firstChild: Fiber,
3186 lastChild: null | Fiber, // non-inclusive
@@ -3379,6 +3399,8 @@ export function attach(
3399 // because we don't want to highlight every host node inside of a newly mounted subtree.
3400 }
3401
3402 + trackDebugInfoFromLazyType(fiber);
3403 +
3404 if (fiber.tag === HostHoistable) {
3405 const nearestInstance = reconcilingParent;
3406 if (nearestInstance === null) {
@@ -4208,6 +4230,8 @@ export function attach(
4230 }
4231 }
4232 try {
4233 + trackDebugInfoFromLazyType(nextFiber);
4234 +
4235 if (
4236 nextFiber.tag === HostHoistable &&
4237 prevFiber.memoizedState !== nextFiber.memoizedState