@@ -638,9 +638,13 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
638
638
currentEventTime = NoWork ;
639
639
640
640
if ( didTimeout ) {
641
- // An async update expired.
641
+ // The render task took too long to complete. Mark the current time as
642
+ // expired to synchronously render all expired work in a single batch.
642
643
const currentTime = requestCurrentTime ( ) ;
643
644
markRootExpiredAtTime ( root , currentTime ) ;
645
+ // This will schedule a synchronous callback.
646
+ ensureRootIsScheduled ( root ) ;
647
+ return ;
644
648
}
645
649
646
650
// Determine the next expiration time to work on, using the fields stored
@@ -649,7 +653,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
649
653
if ( expirationTime !== NoWork ) {
650
654
const originalCallbackNode = root . callbackNode ;
651
655
try {
652
- renderRoot ( root , expirationTime , didTimeout ) ;
656
+ renderRoot ( root , expirationTime , false ) ;
653
657
if ( workInProgress !== null ) {
654
658
// There's still work left over. Exit without committing.
655
659
stopInterruptedWorkLoopTimer ( ) ;
@@ -675,7 +679,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
675
679
// statement, but eslint doesn't know about invariant, so it complains
676
680
// if I do. eslint-disable-next-line no-fallthrough
677
681
case RootErrored : {
678
- if ( ! didTimeout && expirationTime !== Idle ) {
682
+ if ( expirationTime !== Idle ) {
679
683
// If this was an async render, the error may have happened due to
680
684
// a mutation in a concurrent event. Try rendering one more time,
681
685
// synchronously, to see if the error goes away. If there are
@@ -708,7 +712,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
708
712
workInProgressRootLatestProcessedExpirationTime === Sync ;
709
713
if (
710
714
hasNotProcessedNewUpdates &&
711
- ! didTimeout &&
712
715
// do not delay if we're inside an act() scope
713
716
! (
714
717
__DEV__ &&
@@ -781,7 +784,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
781
784
flushSuspensePriorityWarningInDEV ( ) ;
782
785
783
786
if (
784
- ! didTimeout &&
785
787
// do not delay if we're inside an act() scope
786
788
! (
787
789
__DEV__ &&
@@ -879,7 +881,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
879
881
case RootCompleted : {
880
882
// The work completed. Ready to commit.
881
883
if (
882
- ! didTimeout &&
883
884
// do not delay if we're inside an act() scope
884
885
! (
885
886
__DEV__ &&
@@ -1263,6 +1264,8 @@ function renderRoot(
1263
1264
1264
1265
do {
1265
1266
try {
1267
+ // TODO: This is now the only place that `isSync` is used. Consider
1268
+ // outlining the contents of `renderRoot`.
1266
1269
if ( isSync ) {
1267
1270
workLoopSync ( ) ;
1268
1271
} else {
0 commit comments