@@ -33,7 +33,11 @@ import {
3333 mergeLanes ,
3434 pickArbitraryLane ,
3535} from './ReactFiberLane.new' ;
36- import { NoFlags , DidPropagateContext } from './ReactFiberFlags' ;
36+ import {
37+ NoFlags ,
38+ DidPropagateContext ,
39+ NeedsPropagation ,
40+ } from './ReactFiberFlags' ;
3741
3842import invariant from 'shared/invariant' ;
3943import is from 'shared/objectIs' ;
@@ -409,14 +413,6 @@ function propagateContextChanges<T>(
409413 // visit them during render. We should continue propagating the
410414 // siblings, though
411415 nextFiber = null ;
412-
413- // Keep track of subtrees whose propagation we deferred
414- if ( deferredPropagation === null ) {
415- deferredPropagation = new Set ( [ consumer ] ) ;
416- } else {
417- deferredPropagation . add ( consumer ) ;
418- }
419- nextFiber = null ;
420416 }
421417
422418 // Since we already found a match, we can stop traversing the
@@ -513,29 +509,14 @@ export function propagateParentContextChangesToDeferredTree(
513509 ) ;
514510}
515511
516- // Used by lazy context propagation algorithm. When we find a context dependency
517- // match, we don't propagate the changes any further into that fiber's subtree.
518- // We add the matched fibers to this set. Later, if something inside that
519- // subtree bails out of rendering, the presence of a parent fiber in this Set
520- // tells us that we need to continue propagating.
521- //
522- // This is a set of _current_ fibers, not work-in-progress fibers. That's why
523- // it's a set instead of a flag on the fiber.
524- let deferredPropagation: Set< Fiber > | null = null;
525-
526- export function resetDeferredContextPropagation() {
527- // This is called by prepareFreshStack
528- deferredPropagation = null ;
529- }
530-
531512function propagateParentContextChanges(
532513 current: Fiber,
533514 workInProgress: Fiber,
534515 renderLanes: Lanes,
535516 forcePropagateEntireTree: boolean,
536517) {
537518 if ( ! enableLazyContextPropagation ) {
538- return false ;
519+ return ;
539520 }
540521
541522 // Collect all the parent providers that changed. Since this is usually small
@@ -544,58 +525,36 @@ function propagateParentContextChanges(
544525 let parent = workInProgress;
545526 let isInsidePropagationBailout = false;
546527 while (parent !== null) {
547- const currentParent = parent . alternate ;
548- invariant (
549- currentParent !== null ,
550- 'Should have a current fiber. This is a bug in React.' ,
551- ) ;
552-
553528 if ( ! isInsidePropagationBailout ) {
554- if ( deferredPropagation === null ) {
555- if ( ( parent . flags & DidPropagateContext ) !== NoFlags ) {
556- break ;
557- }
558- } else {
559- if ( currentParent !== null && deferredPropagation . has ( currentParent ) ) {
560- // We're inside a subtree that previously bailed out of propagation.
561- // We must disregard the the DidPropagateContext flag as we continue
562- // searching for parent providers.
563- isInsidePropagationBailout = true ;
564- // We know that none of the providers in between the propagation
565- // bailout and the nearest render bailout above that could have
566- // changed. So we can skip those.
567- do {
568- parent = parent . return ;
569- invariant (
570- parent !== null ,
571- 'Expected to find a bailed out fiber. This is a bug in React.' ,
572- ) ;
573- } while ( ( parent . flags & DidPropagateContext ) === NoFlags ) ;
574- } else if ((parent.flags & DidPropagateContext ) !== NoFlags ) {
575- break ;
576- }
529+ if ( ( parent . flags & NeedsPropagation ) !== NoFlags ) {
530+ isInsidePropagationBailout = true ;
531+ } else if ((parent.flags & DidPropagateContext ) !== NoFlags ) {
532+ break ;
577533 }
578534 }
579535
580536 if ( parent . tag === ContextProvider ) {
581- if ( currentParent !== null ) {
582- const oldProps = currentParent . memoizedProps ;
583- if ( oldProps !== null ) {
584- const providerType : ReactProviderType < any > = parent . type ;
585- const context : ReactContext < any > = providerType . _context ;
586-
587- const newProps = parent . pendingProps ;
588- const newValue = newProps . value ;
589-
590- const oldValue = oldProps . value ;
591-
592- const changedBits = calculateChangedBits ( context , newValue , oldValue ) ;
593- if ( changedBits !== 0 ) {
594- if ( contexts !== null ) {
595- contexts . push ( context , changedBits ) ;
596- } else {
597- contexts = [ context , changedBits ] ;
598- }
537+ const currentParent = parent . alternate ;
538+ invariant (
539+ currentParent !== null ,
540+ 'Should have a current fiber. This is a bug in React.' ,
541+ ) ;
542+ const oldProps = currentParent . memoizedProps ;
543+ if ( oldProps !== null ) {
544+ const providerType : ReactProviderType < any > = parent . type ;
545+ const context : ReactContext < any > = providerType . _context ;
546+
547+ const newProps = parent . pendingProps ;
548+ const newValue = newProps . value ;
549+
550+ const oldValue = oldProps . value ;
551+
552+ const changedBits = calculateChangedBits ( context , newValue , oldValue ) ;
553+ if ( changedBits !== 0 ) {
554+ if ( contexts !== null ) {
555+ contexts . push ( context , changedBits ) ;
556+ } else {
557+ contexts = [ context , changedBits ] ;
599558 }
600559 }
601560 }
@@ -628,10 +587,10 @@ function propagateParentContextChanges(
628587 //
629588 // Unfortunately, though, we need to ignore this flag when we're inside a
630589 // tree whose context propagation was deferred — that's what the
631- // `deferredPropagation` set is for.
590+ // `NeedsPropagation` flag is for.
632591 //
633- // If we could instead bail out before entering the siblings' beging phase,
634- // then we could remove both `DidPropagateContext` and `deferredPropagation `.
592+ // If we could instead bail out before entering the siblings' begin phase,
593+ // then we could remove both `DidPropagateContext` and `NeedsPropagation `.
635594 // Consider this as part of the next refactor to the fiber tree structure.
636595 workInProgress.flags |= DidPropagateContext;
637596}
@@ -750,6 +709,9 @@ export function readContext<T>(
750709 // TODO: This is an old field. Delete it.
751710 responders : null ,
752711 } ;
712+ if ( enableLazyContextPropagation ) {
713+ currentlyRenderingFiber . flags |= NeedsPropagation ;
714+ }
753715 } else {
754716 // Append a new context item.
755717 lastContextDependency = lastContextDependency . next = contextItem ;
0 commit comments