MCPcopy
hub / github.com/facebook/react / trackUsedThenable

Function trackUsedThenable

packages/react-reconciler/src/ReactFiberThenable.js:107–287  ·  view source on GitHub ↗
(
  thenableState: ThenableState,
  thenable: Thenable<T>,
  index: number,
)

Source from the content-addressed store, hash-verified

105}
106
107export function trackUsedThenable<T>(
108 thenableState: ThenableState,
109 thenable: Thenable<T>,
110 index: number,
111): T {
112 if (__DEV__ && ReactSharedInternals.actQueue !== null) {
113 ReactSharedInternals.didUsePromise = true;
114 }
115 const trackedThenables = getThenablesFromState(thenableState);
116 const previous = trackedThenables[index];
117 if (previous === undefined) {
118 trackedThenables.push(thenable);
119 } else {
120 if (previous !== thenable) {
121 // Reuse the previous thenable, and drop the new one. We can assume
122 // they represent the same value, because components are idempotent.
123
124 if (__DEV__) {
125 const thenableStateDev: ThenableStateDev = (thenableState: any);
126 if (!thenableStateDev.didWarnAboutUncachedPromise) {
127 // We should only warn the first time an uncached thenable is
128 // discovered per component, because if there are multiple, the
129 // subsequent ones are likely derived from the first.
130 //
131 // We track this on the thenableState instead of deduping using the
132 // component name like we usually do, because in the case of a
133 // promise-as-React-node, the owner component is likely different from
134 // the parent that's currently being reconciled. We'd have to track
135 // the owner using state, which we're trying to move away from. Though
136 // since this is dev-only, maybe that'd be OK.
137 //
138 // However, another benefit of doing it this way is we might
139 // eventually have a thenableState per memo/Forget boundary instead
140 // of per component, so this would allow us to have more
141 // granular warnings.
142 thenableStateDev.didWarnAboutUncachedPromise = true;
143
144 // TODO: This warning should link to a corresponding docs page.
145 console.error(
146 'A component was suspended by an uncached promise. Creating ' +
147 'promises inside a Client Component or hook is not yet ' +
148 'supported, except via a Suspense-compatible library or framework.',
149 );
150 }
151 }
152
153 // Avoid an unhandled rejection errors for the Promises that we'll
154 // intentionally ignore.
155 thenable.then(noop, noop);
156 thenable = previous;
157 }
158 }
159
160 if (__DEV__ && enableAsyncDebugInfo && thenable._debugInfo === undefined) {
161 // In DEV mode if the thenable that we observed had no debug info, then we add
162 // an inferred debug info so that we're able to track its potential I/O uniquely.
163 // We don't know the real start time since the I/O could have started much
164 // earlier and this could even be a cached Promise. Could be misleading.

Callers 2

ReactFiberHooks.jsFile · 0.90
unwrapThenableFunction · 0.90

Calls 6

getWorkInProgressRootFunction · 0.90
getThenablesFromStateFunction · 0.85
pushMethod · 0.65
errorMethod · 0.65
thenMethod · 0.65

Tested by

no test coverage detected