@@ -22,6 +22,7 @@ import type {
22
22
TransitionAbort ,
23
23
} from './ReactFiberTracingMarkerComponent.new' ;
24
24
import type { OffscreenInstance } from './ReactFiberOffscreenComponent' ;
25
+ import type { ThenableState } from './ReactFiberThenable.new' ;
25
26
26
27
import {
27
28
warnAboutDeprecatedLifecycles ,
@@ -265,10 +266,8 @@ import {
265
266
} from './ReactFiberAct.new' ;
266
267
import { processTransitionCallbacks } from './ReactFiberTracingMarkerComponent.new' ;
267
268
import {
268
- resetWakeableStateAfterEachAttempt ,
269
- resetThenableStateOnCompletion ,
270
- suspendedThenableDidResolve ,
271
- isTrackingSuspendedThenable ,
269
+ getThenableStateAfterSuspending ,
270
+ isThenableStateResolved ,
272
271
} from './ReactFiberThenable.new' ;
273
272
import { schedulePostPaintCallback } from './ReactPostPaintCallback' ;
274
273
@@ -315,6 +314,7 @@ let workInProgressRootRenderLanes: Lanes = NoLanes;
315
314
// immediately instead of unwinding the stack.
316
315
let workInProgressIsSuspended : boolean = false ;
317
316
let workInProgressThrownValue : mixed = null ;
317
+ let workInProgressSuspendedThenableState : ThenableState | null = null ;
318
318
319
319
// Whether a ping listener was attached during this render. This is slightly
320
320
// different that whether something suspended, because we don't add multiple
@@ -1686,15 +1686,14 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
1686
1686
) ;
1687
1687
interruptedWork = interruptedWork . return ;
1688
1688
}
1689
- resetWakeableStateAfterEachAttempt ( ) ;
1690
- resetThenableStateOnCompletion ( ) ;
1691
1689
}
1692
1690
workInProgressRoot = root ;
1693
1691
const rootWorkInProgress = createWorkInProgress ( root . current , null ) ;
1694
1692
workInProgress = rootWorkInProgress ;
1695
1693
workInProgressRootRenderLanes = renderLanes = lanes ;
1696
1694
workInProgressIsSuspended = false ;
1697
1695
workInProgressThrownValue = null ;
1696
+ workInProgressSuspendedThenableState = null ;
1698
1697
workInProgressRootDidAttachPingListener = false ;
1699
1698
workInProgressRootExitStatus = RootInProgress ;
1700
1699
workInProgressRootFatalError = null ;
@@ -1729,6 +1728,7 @@ function handleThrow(root, thrownValue): void {
1729
1728
// as suspending the execution of the work loop.
1730
1729
workInProgressIsSuspended = true ;
1731
1730
workInProgressThrownValue = thrownValue ;
1731
+ workInProgressSuspendedThenableState = getThenableStateAfterSuspending ( ) ;
1732
1732
1733
1733
const erroredWork = workInProgress ;
1734
1734
if ( erroredWork === null ) {
@@ -2014,7 +2014,7 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2014
2014
break ;
2015
2015
} catch ( thrownValue ) {
2016
2016
handleThrow ( root , thrownValue ) ;
2017
- if ( isTrackingSuspendedThenable ( ) ) {
2017
+ if ( workInProgressSuspendedThenableState !== null ) {
2018
2018
// If this fiber just suspended, it's possible the data is already
2019
2019
// cached. Yield to the main thread to give it a chance to ping. If
2020
2020
// it does, we can retry immediately without unwinding the stack.
@@ -2117,13 +2117,14 @@ function resumeSuspendedUnitOfWork(
2117
2117
// instead of unwinding the stack. It's a separate function to keep the
2118
2118
// additional logic out of the work loop's hot path.
2119
2119
2120
- const wasPinged = suspendedThenableDidResolve ( ) ;
2121
- resetWakeableStateAfterEachAttempt ( ) ;
2120
+ const wasPinged =
2121
+ workInProgressSuspendedThenableState !== null &&
2122
+ isThenableStateResolved ( workInProgressSuspendedThenableState ) ;
2122
2123
2123
2124
if ( ! wasPinged ) {
2124
2125
// The thenable wasn't pinged. Return to the normal work loop. This will
2125
2126
// unwind the stack, and potentially result in showing a fallback.
2126
- resetThenableStateOnCompletion ( ) ;
2127
+ workInProgressSuspendedThenableState = null ;
2127
2128
2128
2129
const returnFiber = unitOfWork . return ;
2129
2130
if ( returnFiber === null || workInProgressRoot === null ) {
@@ -2188,7 +2189,7 @@ function resumeSuspendedUnitOfWork(
2188
2189
// The begin phase finished successfully without suspending. Reset the state
2189
2190
// used to track the fiber while it was suspended. Then return to the normal
2190
2191
// work loop.
2191
- resetThenableStateOnCompletion ( ) ;
2192
+ workInProgressSuspendedThenableState = null ;
2192
2193
2193
2194
resetCurrentDebugFiberInDEV ( ) ;
2194
2195
unitOfWork . memoizedProps = unitOfWork . pendingProps ;
@@ -2202,6 +2203,10 @@ function resumeSuspendedUnitOfWork(
2202
2203
ReactCurrentOwner . current = null ;
2203
2204
}
2204
2205
2206
+ export function getSuspendedThenableState ( ) : ThenableState | null {
2207
+ return workInProgressSuspendedThenableState ;
2208
+ }
2209
+
2205
2210
function completeUnitOfWork ( unitOfWork : Fiber ) : void {
2206
2211
// Attempt to complete the current unit of work, then move to the next
2207
2212
// sibling. If there are no more siblings, return to the parent fiber.
0 commit comments