@@ -322,7 +322,7 @@ const SuspendedOnError: SuspendedReason = 1;
322322const SuspendedOnData : SuspendedReason = 2 ;
323323const SuspendedOnImmediate : SuspendedReason = 3 ;
324324const SuspendedOnDeprecatedThrowPromise : SuspendedReason = 4 ;
325- const SuspendedAndReadyToUnwind : SuspendedReason = 5 ;
325+ const SuspendedAndReadyToContinue : SuspendedReason = 5 ;
326326const SuspendedOnHydration : SuspendedReason = 6 ;
327327
328328// When this is true, the work-in-progress fiber just suspended (or errored) and
@@ -892,6 +892,18 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
892892 return ;
893893 }
894894
895+ // If this root is currently suspended and waiting for data to resolve, don't
896+ // schedule a task to render it. We'll either wait for a ping, or wait to
897+ // receive an update.
898+ if (
899+ workInProgressSuspendedReason === SuspendedOnData &&
900+ workInProgressRoot === root
901+ ) {
902+ root . callbackPriority = NoLane ;
903+ root . callbackNode = null ;
904+ return ;
905+ }
906+
895907 // We use the highest priority lane to represent the priority of the callback.
896908 const newCallbackPriority = getHighestPriorityLane ( nextLanes ) ;
897909
@@ -1153,20 +1165,6 @@ function performConcurrentWorkOnRoot(
11531165 if ( root . callbackNode === originalCallbackNode ) {
11541166 // The task node scheduled for this root is the same one that's
11551167 // currently executed. Need to return a continuation.
1156- if (
1157- workInProgressSuspendedReason === SuspendedOnData &&
1158- workInProgressRoot === root
1159- ) {
1160- // Special case: The work loop is currently suspended and waiting for
1161- // data to resolve. Unschedule the current task.
1162- //
1163- // TODO: The factoring is a little weird. Arguably this should be checked
1164- // in ensureRootIsScheduled instead. I went back and forth, not totally
1165- // sure yet.
1166- root . callbackPriority = NoLane ;
1167- root . callbackNode = null ;
1168- return null ;
1169- }
11701168 return performConcurrentWorkOnRoot . bind ( null , root ) ;
11711169 }
11721170 return null ;
@@ -1858,7 +1856,7 @@ function handleThrow(root: FiberRoot, thrownValue: any): void {
18581856 case SuspendedOnData :
18591857 case SuspendedOnImmediate :
18601858 case SuspendedOnDeprecatedThrowPromise :
1861- case SuspendedAndReadyToUnwind : {
1859+ case SuspendedAndReadyToContinue : {
18621860 const wakeable : Wakeable = ( thrownValue : any ) ;
18631861 markComponentSuspended (
18641862 erroredWork ,
@@ -2216,6 +2214,17 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
22162214 // `status` field, but if the promise already has a status, we won't
22172215 // have added a listener until right here.
22182216 const onResolution = ( ) = > {
2217+ // Check if the root is still suspended on this promise.
2218+ if (
2219+ workInProgressSuspendedReason === SuspendedOnData &&
2220+ workInProgressRoot === root
2221+ ) {
2222+ // Mark the root as ready to continue rendering.
2223+ workInProgressSuspendedReason = SuspendedAndReadyToContinue ;
2224+ }
2225+ // Ensure the root is scheduled. We should do this even if we're
2226+ // currently working on a different root, so that we resume
2227+ // rendering later.
22192228 ensureRootIsScheduled ( root , now ( ) ) ;
22202229 } ;
22212230 thenable . then ( onResolution , onResolution ) ;
@@ -2225,10 +2234,10 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
22252234 // If this fiber just suspended, it's possible the data is already
22262235 // cached. Yield to the main thread to give it a chance to ping. If
22272236 // it does, we can retry immediately without unwinding the stack.
2228- workInProgressSuspendedReason = SuspendedAndReadyToUnwind ;
2237+ workInProgressSuspendedReason = SuspendedAndReadyToContinue ;
22292238 break outer ;
22302239 }
2231- case SuspendedAndReadyToUnwind : {
2240+ case SuspendedAndReadyToContinue : {
22322241 const thenable : Thenable < mixed > = ( thrownValue : any ) ;
22332242 if ( isThenableResolved ( thenable ) ) {
22342243 // The data resolved. Try rendering the component again.
0 commit comments