@@ -638,9 +638,13 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
638638 currentEventTime = NoWork ;
639639
640640 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.
642643 const currentTime = requestCurrentTime ( ) ;
643644 markRootExpiredAtTime ( root , currentTime ) ;
645+ // This will schedule a synchronous callback.
646+ ensureRootIsScheduled ( root ) ;
647+ return null ;
644648 }
645649
646650 // Determine the next expiration time to work on, using the fields stored
@@ -649,7 +653,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
649653 if ( expirationTime !== NoWork ) {
650654 const originalCallbackNode = root . callbackNode ;
651655 try {
652- renderRoot ( root , expirationTime , didTimeout ) ;
656+ renderRoot ( root , expirationTime , false ) ;
653657 if ( workInProgress !== null ) {
654658 // There's still work left over. Exit without committing.
655659 stopInterruptedWorkLoopTimer ( ) ;
@@ -675,7 +679,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
675679 // statement, but eslint doesn't know about invariant, so it complains
676680 // if I do. eslint-disable-next-line no-fallthrough
677681 case RootErrored : {
678- if ( ! didTimeout && expirationTime !== Idle ) {
682+ if ( expirationTime !== Idle ) {
679683 // If this was an async render, the error may have happened due to
680684 // a mutation in a concurrent event. Try rendering one more time,
681685 // synchronously, to see if the error goes away. If there are
@@ -708,7 +712,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
708712 workInProgressRootLatestProcessedExpirationTime === Sync ;
709713 if (
710714 hasNotProcessedNewUpdates &&
711- ! didTimeout &&
712715 // do not delay if we're inside an act() scope
713716 ! (
714717 __DEV__ &&
@@ -781,7 +784,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
781784 flushSuspensePriorityWarningInDEV ( ) ;
782785
783786 if (
784- ! didTimeout &&
785787 // do not delay if we're inside an act() scope
786788 ! (
787789 __DEV__ &&
@@ -879,7 +881,6 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
879881 case RootCompleted : {
880882 // The work completed. Ready to commit.
881883 if (
882- ! didTimeout &&
883884 // do not delay if we're inside an act() scope
884885 ! (
885886 __DEV__ &&
@@ -1263,6 +1264,8 @@ function renderRoot(
12631264
12641265 do {
12651266 try {
1267+ // TODO: This is now the only place that `isSync` is used. Consider
1268+ // outlining the contents of `renderRoot`.
12661269 if ( isSync ) {
12671270 workLoopSync ( ) ;
12681271 } else {
0 commit comments