(unitOfWork: Fiber)
| 3271 | } |
| 3272 | |
| 3273 | function completeUnitOfWork(unitOfWork: Fiber): void { |
| 3274 | // Attempt to complete the current unit of work, then move to the next |
| 3275 | // sibling. If there are no more siblings, return to the parent fiber. |
| 3276 | let completedWork: Fiber = unitOfWork; |
| 3277 | do { |
| 3278 | if ((completedWork.flags & Incomplete) !== NoFlags) { |
| 3279 | // This fiber did not complete, because one of its children did not |
| 3280 | // complete. Switch to unwinding the stack instead of completing it. |
| 3281 | // |
| 3282 | // The reason "unwind" and "complete" is interleaved is because when |
| 3283 | // something suspends, we continue rendering the siblings even though |
| 3284 | // they will be replaced by a fallback. |
| 3285 | const skipSiblings = workInProgressRootDidSkipSuspendedSiblings; |
| 3286 | unwindUnitOfWork(completedWork, skipSiblings); |
| 3287 | return; |
| 3288 | } |
| 3289 | |
| 3290 | // The current, flushed, state of this fiber is the alternate. Ideally |
| 3291 | // nothing should rely on this, but relying on it here means that we don't |
| 3292 | // need an additional field on the work in progress. |
| 3293 | const current = completedWork.alternate; |
| 3294 | const returnFiber = completedWork.return; |
| 3295 | |
| 3296 | let next; |
| 3297 | startProfilerTimer(completedWork); |
| 3298 | if (__DEV__) { |
| 3299 | next = runWithFiberInDEV( |
| 3300 | completedWork, |
| 3301 | completeWork, |
| 3302 | current, |
| 3303 | completedWork, |
| 3304 | entangledRenderLanes, |
| 3305 | ); |
| 3306 | } else { |
| 3307 | next = completeWork(current, completedWork, entangledRenderLanes); |
| 3308 | } |
| 3309 | if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { |
| 3310 | // Update render duration assuming we didn't error. |
| 3311 | stopProfilerTimerIfRunningAndRecordIncompleteDuration(completedWork); |
| 3312 | } |
| 3313 | if (next !== null) { |
| 3314 | // Completing this fiber spawned new work. Work on that next. |
| 3315 | workInProgress = next; |
| 3316 | return; |
| 3317 | } |
| 3318 | |
| 3319 | const siblingFiber = completedWork.sibling; |
| 3320 | if (siblingFiber !== null) { |
| 3321 | // If there is more work to do in this returnFiber, do that next. |
| 3322 | workInProgress = siblingFiber; |
| 3323 | return; |
| 3324 | } |
| 3325 | // Otherwise, return to the parent |
| 3326 | // $FlowFixMe[incompatible-type] we bail out when we get a null |
| 3327 | completedWork = returnFiber; |
| 3328 | // Update the next thing we're working on in case something throws. |
| 3329 | workInProgress = completedWork; |
| 3330 | } while (completedWork !== null); |
no test coverage detected