@@ -20,9 +20,12 @@ import type {SharedQueue} from './ReactUpdateQueue.new';
20
20
import { isPrimaryRenderer } from './ReactFiberHostConfig' ;
21
21
import { createCursor , push , pop } from './ReactFiberStack.new' ;
22
22
import {
23
+ ContextConsumer ,
23
24
ContextProvider ,
24
25
ClassComponent ,
25
26
DehydratedFragment ,
27
+ OffscreenComponent ,
28
+ SuspenseComponent ,
26
29
} from './ReactWorkTags' ;
27
30
import {
28
31
NoLanes ,
@@ -157,6 +160,10 @@ export function scheduleWorkOnParentPath(
157
160
! isSubsetOfLanes ( alternate . childLanes , renderLanes )
158
161
) {
159
162
alternate . childLanes = mergeLanes ( alternate . childLanes , renderLanes ) ;
163
+ } else {
164
+ // Neither alternate was updated, which means the rest of the
165
+ // ancestor path already has sufficient priority.
166
+ break ;
160
167
}
161
168
node = node.return;
162
169
}
@@ -361,6 +368,66 @@ function propagateContextChanges<T>(
361
368
}
362
369
scheduleWorkOnParentPath ( consumer . return , renderLanes ) ;
363
370
371
+ // If Context.Consumer is a descendant of Suspense,
372
+ // `scheduleWorkOnParentPath` may break before it get to Suspense.
373
+ // Schedule work to avoid bailout before Context.Consumer receives the value.
374
+ const contextConsumerIsDescendantOfSuspense =
375
+ workInProgress . tag === SuspenseComponent &&
376
+ workInProgress . child . tag === OffscreenComponent &&
377
+ consumer . tag === ContextConsumer ;
378
+ if ( contextConsumerIsDescendantOfSuspense ) {
379
+ console . log ( ' contextConsumerWrappedBySuspense' ) ;
380
+ if ( ! isSubsetOfLanes ( workInProgress . childLanes , renderLanes ) ) {
381
+ workInProgress . childLanes = mergeLanes (
382
+ workInProgress . childLanes ,
383
+ renderLanes ,
384
+ ) ;
385
+ if ( workInProgress . alternate !== null ) {
386
+ workInProgress . alternate . childLanes = mergeLanes (
387
+ workInProgress . alternate . childLanes ,
388
+ renderLanes ,
389
+ ) ;
390
+ }
391
+ } else if (
392
+ workInProgress . alternate !== null &&
393
+ ! isSubsetOfLanes (
394
+ workInProgress . alternate . childLanes ,
395
+ renderLanes ,
396
+ )
397
+ ) {
398
+ workInProgress . alternate . childLanes = mergeLanes (
399
+ workInProgress . alternate . childLanes ,
400
+ renderLanes ,
401
+ ) ;
402
+ }
403
+ const primaryChildFragment = workInProgress . child ;
404
+ if (
405
+ ! isSubsetOfLanes ( primaryChildFragment . childLanes , renderLanes )
406
+ ) {
407
+ primaryChildFragment . childLanes = mergeLanes (
408
+ primaryChildFragment . childLanes ,
409
+ renderLanes ,
410
+ ) ;
411
+ if ( primaryChildFragment . alternate !== null ) {
412
+ primaryChildFragment . alternate . childLanes = mergeLanes (
413
+ primaryChildFragment . alternate . childLanes ,
414
+ renderLanes ,
415
+ ) ;
416
+ }
417
+ } else if (
418
+ primaryChildFragment . alternate !== null &&
419
+ ! isSubsetOfLanes (
420
+ primaryChildFragment . alternate . childLanes ,
421
+ renderLanes ,
422
+ )
423
+ ) {
424
+ primaryChildFragment . alternate . childLanes = mergeLanes (
425
+ primaryChildFragment . alternate . childLanes ,
426
+ renderLanes ,
427
+ ) ;
428
+ }
429
+ }
430
+
364
431
if ( ! forcePropagateEntireTree ) {
365
432
// During lazy propagation, when we find a match, we can defer
366
433
// propagating changes to the children, because we're going to
0 commit comments