@@ -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' ;
@@ -292,9 +296,6 @@ function propagateContextChange_eager<T>(
292
296
}
293
297
dependency = dependency . next ;
294
298
}
295
- } else if ( fiber . tag === ContextProvider ) {
296
- // Don't scan deeper if this is a matching provider
297
- nextFiber = fiber . type === workInProgress . type ? null : fiber . child ;
298
299
} else if (
299
300
enableSuspenseServerRenderer &&
300
301
fiber . tag === DehydratedFragment
@@ -409,14 +410,6 @@ function propagateContextChanges<T>(
409
410
// visit them during render. We should continue propagating the
410
411
// siblings, though
411
412
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
413
}
421
414
422
415
// Since we already found a match, we can stop traversing the
@@ -513,29 +506,14 @@ export function propagateParentContextChangesToDeferredTree(
513
506
) ;
514
507
}
515
508
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
509
function propagateParentContextChanges(
532
510
current: Fiber,
533
511
workInProgress: Fiber,
534
512
renderLanes: Lanes,
535
513
forcePropagateEntireTree: boolean,
536
514
) {
537
515
if ( ! enableLazyContextPropagation ) {
538
- return false ;
516
+ return ;
539
517
}
540
518
541
519
// Collect all the parent providers that changed. Since this is usually small
@@ -544,58 +522,36 @@ function propagateParentContextChanges(
544
522
let parent = workInProgress;
545
523
let isInsidePropagationBailout = false;
546
524
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
525
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
- }
526
+ if ( ( parent . flags & NeedsPropagation ) !== NoFlags ) {
527
+ isInsidePropagationBailout = true ;
528
+ } else if ((parent.flags & DidPropagateContext ) !== NoFlags ) {
529
+ break ;
577
530
}
578
531
}
579
532
580
533
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
- }
534
+ const currentParent = parent . alternate ;
535
+ invariant (
536
+ currentParent !== null ,
537
+ 'Should have a current fiber. This is a bug in React.' ,
538
+ ) ;
539
+ const oldProps = currentParent . memoizedProps ;
540
+ if ( oldProps !== null ) {
541
+ const providerType : ReactProviderType < any > = parent . type ;
542
+ const context : ReactContext < any > = providerType . _context ;
543
+
544
+ const newProps = parent . pendingProps ;
545
+ const newValue = newProps . value ;
546
+
547
+ const oldValue = oldProps . value ;
548
+
549
+ const changedBits = calculateChangedBits ( context , newValue , oldValue ) ;
550
+ if ( changedBits !== 0 ) {
551
+ if ( contexts !== null ) {
552
+ contexts . push ( context , changedBits ) ;
553
+ } else {
554
+ contexts = [ context , changedBits ] ;
599
555
}
600
556
}
601
557
}
@@ -628,10 +584,10 @@ function propagateParentContextChanges(
628
584
//
629
585
// Unfortunately, though, we need to ignore this flag when we're inside a
630
586
// tree whose context propagation was deferred — that's what the
631
- // `deferredPropagation` set is for.
587
+ // `NeedsPropagation` flag is for.
632
588
//
633
- // If we could instead bail out before entering the siblings' beging phase,
634
- // then we could remove both `DidPropagateContext` and `deferredPropagation `.
589
+ // If we could instead bail out before entering the siblings' begin phase,
590
+ // then we could remove both `DidPropagateContext` and `NeedsPropagation `.
635
591
// Consider this as part of the next refactor to the fiber tree structure.
636
592
workInProgress.flags |= DidPropagateContext;
637
593
}
@@ -750,6 +706,7 @@ export function readContext<T>(
750
706
// TODO: This is an old field. Delete it.
751
707
responders : null ,
752
708
} ;
709
+ currentlyRenderingFiber . flags |= NeedsPropagation ;
753
710
} else {
754
711
// Append a new context item.
755
712
lastContextDependency = lastContextDependency . next = contextItem ;
0 commit comments