@@ -181,6 +181,7 @@ import {requestCurrentTransition, NoTransition} from './ReactFiberTransition';
181
181
import {
182
182
SelectiveHydrationException ,
183
183
beginWork as originalBeginWork ,
184
+ replayFunctionComponent ,
184
185
} from './ReactFiberBeginWork.new' ;
185
186
import { completeWork } from './ReactFiberCompleteWork.new' ;
186
187
import { unwindWork , unwindInterruptedWork } from './ReactFiberUnwindWork.new' ;
@@ -282,6 +283,7 @@ import {
282
283
getSuspenseHandler ,
283
284
isBadSuspenseFallback ,
284
285
} from './ReactFiberSuspenseContext.new' ;
286
+ import { resolveDefaultProps } from './ReactFiberLazyComponent.new' ;
285
287
286
288
const ceil = Math . ceil ;
287
289
@@ -2353,22 +2355,79 @@ function replaySuspendedUnitOfWork(
2353
2355
// This is a fork of performUnitOfWork specifcally for replaying a fiber that
2354
2356
// just suspended.
2355
2357
//
2356
- // Instead of unwinding the stack and potentially showing a fallback, unwind
2357
- // only the last stack frame, reset the fiber, and try rendering it again.
2358
2358
const current = unitOfWork . alternate ;
2359
- resetSuspendedWorkLoopOnUnwind ( ) ;
2360
- unwindInterruptedWork ( current , unitOfWork , workInProgressRootRenderLanes ) ;
2361
- unitOfWork = workInProgress = resetWorkInProgress ( unitOfWork , renderLanes ) ;
2362
-
2363
2359
setCurrentDebugFiberInDEV ( unitOfWork ) ;
2364
2360
2365
2361
let next ;
2366
- if ( enableProfilerTimer && ( unitOfWork . mode & ProfileMode ) !== NoMode ) {
2362
+ setCurrentDebugFiberInDEV ( unitOfWork ) ;
2363
+ const isProfilingMode =
2364
+ enableProfilerTimer && ( unitOfWork . mode & ProfileMode ) !== NoMode ;
2365
+ if ( isProfilingMode ) {
2367
2366
startProfilerTimer ( unitOfWork ) ;
2368
- next = beginWork ( current , unitOfWork , renderLanes ) ;
2367
+ }
2368
+ switch ( unitOfWork . tag ) {
2369
+ case IndeterminateComponent: {
2370
+ // Because it suspended with `use`, we can assume it's a
2371
+ // function component.
2372
+ unitOfWork . tag = FunctionComponent ;
2373
+ // Fallthrough to the next branch.
2374
+ }
2375
+ // eslint-disable-next-line no-fallthrough
2376
+ case FunctionComponent:
2377
+ case ForwardRef: {
2378
+ // Resolve `defaultProps`. This logic is copied from `beginWork`.
2379
+ // TODO: Consider moving this switch statement into that module. Also,
2380
+ // could maybe use this as an opportunity to say `use` doesn't work with
2381
+ // `defaultProps` :)
2382
+ const Component = unitOfWork . type ;
2383
+ const unresolvedProps = unitOfWork . pendingProps ;
2384
+ const resolvedProps =
2385
+ unitOfWork . elementType === Component
2386
+ ? unresolvedProps
2387
+ : resolveDefaultProps ( Component , unresolvedProps ) ;
2388
+ next = replayFunctionComponent (
2389
+ current ,
2390
+ unitOfWork ,
2391
+ resolvedProps ,
2392
+ Component ,
2393
+ thenableState ,
2394
+ workInProgressRootRenderLanes ,
2395
+ ) ;
2396
+ break ;
2397
+ }
2398
+ case SimpleMemoComponent : {
2399
+ const Component = unitOfWork . type ;
2400
+ const nextProps = unitOfWork . pendingProps ;
2401
+ next = replayFunctionComponent (
2402
+ current ,
2403
+ unitOfWork ,
2404
+ nextProps ,
2405
+ Component ,
2406
+ thenableState ,
2407
+ workInProgressRootRenderLanes ,
2408
+ ) ;
2409
+ break ;
2410
+ }
2411
+ default: {
2412
+ if ( __DEV__ ) {
2413
+ console . error (
2414
+ 'Unexpected type of work: %s, Currently only function ' +
2415
+ 'components are replayed after suspending. This is a bug in React.' ,
2416
+ unitOfWork . tag ,
2417
+ ) ;
2418
+ }
2419
+ resetSuspendedWorkLoopOnUnwind ( ) ;
2420
+ unwindInterruptedWork ( current , unitOfWork , workInProgressRootRenderLanes ) ;
2421
+ unitOfWork = workInProgress = resetWorkInProgress (
2422
+ unitOfWork ,
2423
+ renderLanes ,
2424
+ ) ;
2425
+ next = beginWork ( current , unitOfWork , renderLanes ) ;
2426
+ break ;
2427
+ }
2428
+ }
2429
+ if ( isProfilingMode ) {
2369
2430
stopProfilerTimerIfRunningAndRecordDelta ( unitOfWork , true) ;
2370
- } else {
2371
- next = beginWork ( current , unitOfWork , renderLanes ) ;
2372
2431
}
2373
2432
2374
2433
// The begin phase finished successfully without suspending. Reset the state
0 commit comments