diff --git a/packages/react/src/ReactLazy.js b/packages/react/src/ReactLazy.js index 55b1690b7ca..47f37afbae2 100644 --- a/packages/react/src/ReactLazy.js +++ b/packages/react/src/ReactLazy.js @@ -20,6 +20,8 @@ import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags'; import {REACT_LAZY_TYPE} from 'shared/ReactSymbols'; +import noop from 'shared/noop'; + const Uninitialized = -1; const Pending = 0; const Resolved = 1; @@ -67,12 +69,20 @@ export type LazyComponent = { function lazyInitializer(payload: Payload): T { if (payload._status === Uninitialized) { + let resolveDebugValue: (void | T) => void = (null: any); + let rejectDebugValue: mixed => void = (null: any); if (__DEV__ && enableAsyncDebugInfo) { const ioInfo = payload._ioInfo; if (ioInfo != null) { // Mark when we first kicked off the lazy request. // $FlowFixMe[cannot-write] ioInfo.start = ioInfo.end = performance.now(); + // Stash a Promise for introspection of the value later. + // $FlowFixMe[cannot-write] + ioInfo.value = new Promise((resolve, reject) => { + resolveDebugValue = resolve; + rejectDebugValue = reject; + }); } } const ctor = payload._result; @@ -92,12 +102,20 @@ function lazyInitializer(payload: Payload): T { const resolved: ResolvedPayload = (payload: any); resolved._status = Resolved; resolved._result = moduleObject; - if (__DEV__) { + if (__DEV__ && enableAsyncDebugInfo) { const ioInfo = payload._ioInfo; if (ioInfo != null) { // Mark the end time of when we resolved. // $FlowFixMe[cannot-write] ioInfo.end = performance.now(); + // Surface the default export as the resolved "value" for debug purposes. + const debugValue = + moduleObject == null ? undefined : moduleObject.default; + resolveDebugValue(debugValue); + // $FlowFixMe + ioInfo.value.status = 'fulfilled'; + // $FlowFixMe + ioInfo.value.value = debugValue; } // Make the thenable introspectable if (thenable.status === undefined) { @@ -124,6 +142,14 @@ function lazyInitializer(payload: Payload): T { // Mark the end time of when we rejected. // $FlowFixMe[cannot-write] ioInfo.end = performance.now(); + // Hide unhandled rejections. + // $FlowFixMe + ioInfo.value.then(noop, noop); + rejectDebugValue(error); + // $FlowFixMe + ioInfo.value.status = 'rejected'; + // $FlowFixMe + ioInfo.value.reason = error; } // Make the thenable introspectable if (thenable.status === undefined) { @@ -139,9 +165,6 @@ function lazyInitializer(payload: Payload): T { if (__DEV__ && enableAsyncDebugInfo) { const ioInfo = payload._ioInfo; if (ioInfo != null) { - // Stash the thenable for introspection of the value later. - // $FlowFixMe[cannot-write] - ioInfo.value = thenable; const displayName = thenable.displayName; if (typeof displayName === 'string') { // $FlowFixMe[cannot-write]