@@ -540,6 +540,35 @@ export function scheduleUpdateOnFiber(
540540 return null ;
541541 }
542542
543+ // Mark that the root has a pending update.
544+ markRootUpdated(root, lane, eventTime);
545+
546+ if (root === workInProgressRoot) {
547+ // Received an update to a tree that's in the middle of rendering. Mark
548+ // that there was an interleaved update work on this root. Unless the
549+ // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
550+ // phase update. In that case, we don't treat render phase updates as if
551+ // they were interleaved, for backwards compat reasons.
552+ if (
553+ deferRenderPhaseUpdateToNextBatch ||
554+ ( executionContext & RenderContext ) === NoContext
555+ ) {
556+ workInProgressRootUpdatedLanes = mergeLanes (
557+ workInProgressRootUpdatedLanes ,
558+ lane ,
559+ ) ;
560+ }
561+ if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
562+ // The root already suspended with a delay, which means this render
563+ // definitely won't finish. Since we have a new update, let's mark it as
564+ // suspended now, right before marking the incoming update. This has the
565+ // effect of interrupting the current render and switching to the update.
566+ // TODO: Make sure this doesn't override pings that happen while we've
567+ // already started rendering.
568+ markRootSuspended ( root , workInProgressRootRenderLanes ) ;
569+ }
570+ }
571+
543572 // TODO: requestUpdateLanePriority also reads the priority. Pass the
544573 // priority as an argument to that function and this one.
545574 const priorityLevel = getCurrentPriorityLevel ( ) ;
@@ -605,82 +634,47 @@ export function scheduleUpdateOnFiber(
605634// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
606635// on a fiber.
607636function markUpdateLaneFromFiberToRoot (
608- fiber : Fiber ,
637+ sourceFiber : Fiber ,
609638 lane : Lane ,
610639) : FiberRoot | null {
611640 // Update the source fiber's lanes
612- fiber . lanes = mergeLanes ( fiber . lanes , lane ) ;
613- let alternate = fiber . alternate ;
641+ sourceFiber . lanes = mergeLanes ( sourceFiber . lanes , lane ) ;
642+ let alternate = sourceFiber . alternate ;
614643 if ( alternate !== null ) {
615644 alternate . lanes = mergeLanes ( alternate . lanes , lane ) ;
616645 }
617646 if (__DEV__) {
618647 if (
619648 alternate === null &&
620- ( fiber . effectTag & ( Placement | Hydrating ) ) !== NoEffect
649+ ( sourceFiber . effectTag & ( Placement | Hydrating ) ) !== NoEffect
621650 ) {
622- warnAboutUpdateOnNotYetMountedFiberInDEV ( fiber ) ;
651+ warnAboutUpdateOnNotYetMountedFiberInDEV ( sourceFiber ) ;
623652 }
624653 }
625654 // Walk the parent path to the root and update the child expiration time.
626- let node = fiber . return ;
627- let root = null ;
628- if ( node === null && fiber . tag === HostRoot ) {
629- root = fiber . stateNode ;
630- } else {
631- while ( node !== null ) {
632- alternate = node . alternate ;
655+ let node = sourceFiber ;
656+ let parent = sourceFiber . return ;
657+ while ( parent !== null ) {
658+ parent . childLanes = mergeLanes ( parent . childLanes , lane ) ;
659+ alternate = parent . alternate ;
660+ if ( alternate !== null ) {
661+ alternate . childLanes = mergeLanes ( alternate . childLanes , lane ) ;
662+ } else {
633663 if ( __DEV__ ) {
634- if (
635- alternate === null &&
636- ( node . effectTag & ( Placement | Hydrating ) ) !== NoEffect
637- ) {
638- warnAboutUpdateOnNotYetMountedFiberInDEV ( fiber ) ;
664+ if ( ( parent . effectTag & ( Placement | Hydrating ) ) !== NoEffect ) {
665+ warnAboutUpdateOnNotYetMountedFiberInDEV ( sourceFiber ) ;
639666 }
640667 }
641- node . childLanes = mergeLanes ( node . childLanes , lane ) ;
642- if ( alternate !== null ) {
643- alternate . childLanes = mergeLanes ( alternate . childLanes , lane ) ;
644- }
645- if (node.return === null && node . tag === HostRoot ) {
646- root = node . stateNode ;
647- break ;
648- }
649- node = node.return;
650668 }
669+ node = parent ;
670+ parent = parent . return ;
651671 }
652-
653- if ( root !== null ) {
654- // Mark that the root has a pending update.
655- markRootUpdated ( root , lane ) ;
656- if ( workInProgressRoot === root ) {
657- // Received an update to a tree that's in the middle of rendering. Mark
658- // that there was an interleaved update work on this root. Unless the
659- // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
660- // phase update. In that case, we don't treat render phase updates as if
661- // they were interleaved, for backwards compat reasons.
662- if (
663- deferRenderPhaseUpdateToNextBatch ||
664- ( executionContext & RenderContext ) === NoContext
665- ) {
666- workInProgressRootUpdatedLanes = mergeLanes (
667- workInProgressRootUpdatedLanes ,
668- lane ,
669- ) ;
670- }
671- if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
672- // The root already suspended with a delay, which means this render
673- // definitely won't finish. Since we have a new update, let's mark it as
674- // suspended now, right before marking the incoming update. This has the
675- // effect of interrupting the current render and switching to the update.
676- // TODO: Make sure this doesn't override pings that happen while we've
677- // already started rendering.
678- markRootSuspended ( root , workInProgressRootRenderLanes ) ;
679- }
680- }
672+ if ( node . tag === HostRoot ) {
673+ const root : FiberRoot = node . stateNode ;
674+ return root ;
675+ } else {
676+ return null ;
681677 }
682-
683- return root ;
684678}
685679
686680// Use this function to schedule a task for a root. There's only one task per
@@ -2908,6 +2902,7 @@ function captureCommitPhaseErrorOnRoot(
29082902 const eventTime = requestEventTime ( ) ;
29092903 const root = markUpdateLaneFromFiberToRoot ( rootFiber , ( SyncLane : Lane ) ) ;
29102904 if ( root !== null ) {
2905+ markRootUpdated ( root , SyncLane , eventTime ) ;
29112906 ensureRootIsScheduled ( root , eventTime ) ;
29122907 schedulePendingInteractions ( root , SyncLane ) ;
29132908 }
@@ -2944,6 +2939,7 @@ export function captureCommitPhaseError(sourceFiber: Fiber, error: mixed) {
29442939 const eventTime = requestEventTime ( ) ;
29452940 const root = markUpdateLaneFromFiberToRoot ( fiber , ( SyncLane : Lane ) ) ;
29462941 if ( root !== null ) {
2942+ markRootUpdated ( root , SyncLane , eventTime ) ;
29472943 ensureRootIsScheduled ( root , eventTime ) ;
29482944 schedulePendingInteractions ( root , SyncLane ) ;
29492945 }
@@ -3016,6 +3012,7 @@ function retryTimedOutBoundary(boundaryFiber: Fiber, retryLane: Lane) {
30163012 const eventTime = requestEventTime ( ) ;
30173013 const root = markUpdateLaneFromFiberToRoot ( boundaryFiber , retryLane ) ;
30183014 if ( root !== null ) {
3015+ markRootUpdated ( root , retryLane , eventTime ) ;
30193016 ensureRootIsScheduled ( root , eventTime ) ;
30203017 schedulePendingInteractions ( root , retryLane ) ;
30213018 }
0 commit comments