@@ -1085,108 +1085,87 @@ function finishConcurrentRender(
1085
1085
finishedWork : Fiber ,
1086
1086
lanes : Lanes ,
1087
1087
) {
1088
+ // TODO: The fact that most of these branches are identical suggests that some
1089
+ // of the exit statuses are not best modeled as exit statuses and should be
1090
+ // tracked orthogonally.
1088
1091
switch ( exitStatus ) {
1089
1092
case RootInProgress :
1090
1093
case RootFatalErrored : {
1091
1094
throw new Error ( 'Root did not complete. This is a bug in React.' ) ;
1092
1095
}
1093
- case RootErrored : {
1094
- // We should have already attempted to retry this tree. If we reached
1095
- // this point, it errored again. Commit it.
1096
- commitRootWhenReady (
1097
- root ,
1098
- finishedWork ,
1099
- workInProgressRootRecoverableErrors ,
1100
- workInProgressTransitions ,
1101
- lanes ,
1102
- ) ;
1103
- break ;
1104
- }
1105
- case RootSuspended : {
1106
- markRootSuspended ( root , lanes ) ;
1107
-
1108
- // We have an acceptable loading state. We need to figure out if we
1109
- // should immediately commit it or wait a bit.
1110
-
1111
- if (
1112
- includesOnlyRetries ( lanes ) &&
1113
- // do not delay if we're inside an act() scope
1114
- ! shouldForceFlushFallbacksInDEV ( )
1115
- ) {
1116
- // This render only included retries, no updates. Throttle committing
1117
- // retries so that we don't show too many loading states too quickly.
1118
- const msUntilTimeout =
1119
- globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now ( ) ;
1120
- // Don't bother with a very short suspense time.
1121
- if ( msUntilTimeout > 10 ) {
1122
- const nextLanes = getNextLanes ( root , NoLanes ) ;
1123
- if ( nextLanes !== NoLanes ) {
1124
- // There's additional work on this root.
1125
- break ;
1126
- }
1127
-
1128
- // The render is suspended, it hasn't timed out, and there's no
1129
- // lower priority work to do. Instead of committing the fallback
1130
- // immediately, wait for more data to arrive.
1131
- root . timeoutHandle = scheduleTimeout (
1132
- commitRootWhenReady . bind (
1133
- null ,
1134
- root ,
1135
- finishedWork ,
1136
- workInProgressRootRecoverableErrors ,
1137
- workInProgressTransitions ,
1138
- lanes ,
1139
- ) ,
1140
- msUntilTimeout ,
1141
- ) ;
1142
- break ;
1143
- }
1144
- }
1145
- // The work expired. Commit immediately.
1146
- commitRootWhenReady (
1147
- root ,
1148
- finishedWork ,
1149
- workInProgressRootRecoverableErrors ,
1150
- workInProgressTransitions ,
1151
- lanes ,
1152
- ) ;
1153
- break ;
1154
- }
1155
1096
case RootSuspendedWithDelay : {
1156
- markRootSuspended ( root , lanes ) ;
1157
-
1158
1097
if ( includesOnlyTransitions ( lanes ) ) {
1159
1098
// This is a transition, so we should exit without committing a
1160
1099
// placeholder and without scheduling a timeout. Delay indefinitely
1161
1100
// until we receive more data.
1162
- break ;
1101
+ markRootSuspended ( root , lanes ) ;
1102
+ return ;
1163
1103
}
1164
-
1165
1104
// Commit the placeholder.
1166
- commitRootWhenReady (
1167
- root ,
1168
- finishedWork ,
1169
- workInProgressRootRecoverableErrors ,
1170
- workInProgressTransitions ,
1171
- lanes ,
1172
- ) ;
1173
1105
break ;
1174
1106
}
1107
+ case RootErrored :
1108
+ case RootSuspended :
1175
1109
case RootCompleted : {
1176
- // The work completed.
1177
- commitRootWhenReady (
1178
- root ,
1179
- finishedWork ,
1180
- workInProgressRootRecoverableErrors ,
1181
- workInProgressTransitions ,
1182
- lanes ,
1183
- ) ;
1184
1110
break ;
1185
1111
}
1186
1112
default : {
1187
1113
throw new Error ( 'Unknown root exit status.' ) ;
1188
1114
}
1189
1115
}
1116
+
1117
+ if ( shouldForceFlushFallbacksInDEV ( ) ) {
1118
+ // We're inside an `act` scope. Commit immediately.
1119
+ commitRoot (
1120
+ root ,
1121
+ workInProgressRootRecoverableErrors ,
1122
+ workInProgressTransitions ,
1123
+ ) ;
1124
+ } else {
1125
+ if ( includesOnlyRetries ( lanes ) ) {
1126
+ // This render only included retries, no updates. Throttle committing
1127
+ // retries so that we don't show too many loading states too quickly.
1128
+ const msUntilTimeout =
1129
+ globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now ( ) ;
1130
+
1131
+ // Don't bother with a very short suspense time.
1132
+ if ( msUntilTimeout > 10 ) {
1133
+ markRootSuspended ( root , lanes ) ;
1134
+
1135
+ const nextLanes = getNextLanes ( root , NoLanes ) ;
1136
+ if ( nextLanes !== NoLanes ) {
1137
+ // There's additional work we can do on this root. We might as well
1138
+ // attempt to work on that while we're suspended.
1139
+ return ;
1140
+ }
1141
+
1142
+ // The render is suspended, it hasn't timed out, and there's no
1143
+ // lower priority work to do. Instead of committing the fallback
1144
+ // immediately, wait for more data to arrive.
1145
+ // TODO: Combine retry throttling with Suspensey commits. Right now they
1146
+ // run one after the other.
1147
+ root . timeoutHandle = scheduleTimeout (
1148
+ commitRootWhenReady . bind (
1149
+ null ,
1150
+ root ,
1151
+ finishedWork ,
1152
+ workInProgressRootRecoverableErrors ,
1153
+ workInProgressTransitions ,
1154
+ lanes ,
1155
+ ) ,
1156
+ msUntilTimeout ,
1157
+ ) ;
1158
+ return ;
1159
+ }
1160
+ }
1161
+ commitRootWhenReady (
1162
+ root ,
1163
+ finishedWork ,
1164
+ workInProgressRootRecoverableErrors ,
1165
+ workInProgressTransitions ,
1166
+ lanes ,
1167
+ ) ;
1168
+ }
1190
1169
}
1191
1170
1192
1171
function commitRootWhenReady (
@@ -1196,6 +1175,8 @@ function commitRootWhenReady(
1196
1175
transitions : Array < Transition > | null ,
1197
1176
lanes : Lanes ,
1198
1177
) {
1178
+ // TODO: Combine retry throttling with Suspensey commits. Right now they run
1179
+ // one after the other.
1199
1180
if ( includesOnlyNonUrgentLanes ( lanes ) ) {
1200
1181
// Before committing, ask the renderer whether the host tree is ready.
1201
1182
// If it's not, we'll wait until it notifies us.
@@ -1218,22 +1199,15 @@ function commitRootWhenReady(
1218
1199
// us that it's ready. This will be canceled if we start work on the
1219
1200
// root again.
1220
1201
root . cancelPendingCommit = schedulePendingCommit (
1221
- commitRoot . bind (
1222
- null ,
1223
- root ,
1224
- workInProgressRootRecoverableErrors ,
1225
- workInProgressTransitions ,
1226
- ) ,
1202
+ commitRoot . bind ( null , root , recoverableErrors , transitions ) ,
1227
1203
) ;
1204
+ markRootSuspended ( root , lanes ) ;
1228
1205
return ;
1229
1206
}
1230
1207
}
1208
+
1231
1209
// Otherwise, commit immediately.
1232
- commitRoot (
1233
- root ,
1234
- workInProgressRootRecoverableErrors ,
1235
- workInProgressTransitions ,
1236
- ) ;
1210
+ commitRoot ( root , recoverableErrors , transitions ) ;
1237
1211
}
1238
1212
1239
1213
function isRenderConsistentWithExternalStores ( finishedWork : Fiber ) : boolean {
0 commit comments