@@ -33,7 +33,11 @@ import {
33
33
mergeLanes ,
34
34
pickArbitraryLane ,
35
35
} from './ReactFiberLane.new' ;
36
- import { NoFlags , DidPropagateContext } from './ReactFiberFlags' ;
36
+ import {
37
+ NoFlags ,
38
+ DidPropagateContext ,
39
+ NeedsPropagation ,
40
+ } from './ReactFiberFlags' ;
37
41
38
42
import invariant from 'shared/invariant' ;
39
43
import is from 'shared/objectIs' ;
@@ -409,14 +413,6 @@ function propagateContextChanges<T>(
409
413
// visit them during render. We should continue propagating the
410
414
// siblings, though
411
415
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 ;
420
416
}
421
417
422
418
// Since we already found a match, we can stop traversing the
@@ -513,29 +509,14 @@ export function propagateParentContextChangesToDeferredTree(
513
509
) ;
514
510
}
515
511
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
-
531
512
function propagateParentContextChanges(
532
513
current: Fiber,
533
514
workInProgress: Fiber,
534
515
renderLanes: Lanes,
535
516
forcePropagateEntireTree: boolean,
536
517
) {
537
518
if ( ! enableLazyContextPropagation ) {
538
- return false ;
519
+ return ;
539
520
}
540
521
541
522
// Collect all the parent providers that changed. Since this is usually small
@@ -544,58 +525,36 @@ function propagateParentContextChanges(
544
525
let parent = workInProgress;
545
526
let isInsidePropagationBailout = false;
546
527
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
-
553
528
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 ;
577
533
}
578
534
}
579
535
580
536
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 ] ;
599
558
}
600
559
}
601
560
}
@@ -628,10 +587,10 @@ function propagateParentContextChanges(
628
587
//
629
588
// Unfortunately, though, we need to ignore this flag when we're inside a
630
589
// tree whose context propagation was deferred — that's what the
631
- // `deferredPropagation` set is for.
590
+ // `NeedsPropagation` flag is for.
632
591
//
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 `.
635
594
// Consider this as part of the next refactor to the fiber tree structure.
636
595
workInProgress.flags |= DidPropagateContext;
637
596
}
@@ -750,6 +709,9 @@ export function readContext<T>(
750
709
// TODO: This is an old field. Delete it.
751
710
responders : null ,
752
711
} ;
712
+ if ( enableLazyContextPropagation ) {
713
+ currentlyRenderingFiber . flags |= NeedsPropagation ;
714
+ }
753
715
} else {
754
716
// Append a new context item.
755
717
lastContextDependency = lastContextDependency . next = contextItem ;
0 commit comments