@@ -16,6 +16,7 @@ import type {ExpirationTime} from './ReactFiberExpirationTime';
16
16
import type { UpdateQueue } from './ReactUpdateQueue' ;
17
17
import type { Interaction } from 'interaction-tracking/src/InteractionTracking' ;
18
18
import type { PendingInteractionMap } from './ReactFiberRoot' ;
19
+ import type { ContextDependency } from './ReactFiberNewContext' ;
19
20
20
21
import invariant from 'shared/invariant' ;
21
22
import { enableProfilerTimer } from 'shared/ReactFeatureFlags' ;
@@ -77,7 +78,7 @@ if (__DEV__) {
77
78
// During the commit phase, the related interactions are termporarily stored in an Array,
78
79
// So that class components within the sub-tree can associate cascading updates with those events.
79
80
export type ProfilerStateNode = { |
80
- committedInteractions : Array < Interaction > ,
81
+ committedInteractions : Set < Interaction > ,
81
82
pendingInteractionMap : Map < ExpirationTime , Set < Interaction> > ,
82
83
| } ;
83
84
@@ -137,6 +138,9 @@ export type Fiber = {|
137
138
// The state used to create the output
138
139
memoizedState : any ,
139
140
141
+ // A linked-list of contexts that this fiber depends on
142
+ firstContextDependency : ContextDependency < mixed > | null ,
143
+
140
144
// Bitfield that describes properties about the fiber and its subtree. E.g.
141
145
// the AsyncMode flag indicates whether the subtree should be async-by-
142
146
// default. When a fiber is created, it inherits the mode of its
@@ -158,9 +162,12 @@ export type Fiber = {|
158
162
lastEffect : Fiber | null ,
159
163
160
164
// Represents a time in the future by which this work should be completed.
161
- // This is also used to quickly determine if a subtree has no pending changes .
165
+ // Does not include work found in its subtree.
162
166
expirationTime : ExpirationTime ,
163
167
168
+ // This is used to quickly determine if a subtree has no pending changes.
169
+ childExpirationTime : ExpirationTime ,
170
+
164
171
// This is a pooled version of a Fiber. Every fiber that gets updated will
165
172
// eventually have a pair. There are cases when we can clean up pairs to save
166
173
// memory if we need to.
@@ -226,6 +233,7 @@ function FiberNode(
226
233
this . memoizedProps = null ;
227
234
this . updateQueue = null ;
228
235
this . memoizedState = null ;
236
+ this . firstContextDependency = null ;
229
237
230
238
this . mode = mode ;
231
239
@@ -237,6 +245,7 @@ function FiberNode(
237
245
this . lastEffect = null ;
238
246
239
247
this . expirationTime = NoWork ;
248
+ this . childExpirationTime = NoWork ;
240
249
241
250
this . alternate = null ;
242
251
@@ -338,12 +347,21 @@ export function createWorkInProgress(
338
347
}
339
348
}
340
349
341
- workInProgress . expirationTime = expirationTime ;
350
+ // Don't touching the subtree's expiration time, which has not changed.
351
+ workInProgress . childExpirationTime = current . childExpirationTime ;
352
+ if ( pendingProps !== current . pendingProps ) {
353
+ // This fiber has new props.
354
+ workInProgress . expirationTime = expirationTime ;
355
+ } else {
356
+ // This fiber's props have not changed.
357
+ workInProgress . expirationTime = current . expirationTime ;
358
+ }
342
359
343
360
workInProgress . child = current . child ;
344
361
workInProgress . memoizedProps = current . memoizedProps ;
345
362
workInProgress . memoizedState = current . memoizedState ;
346
363
workInProgress . updateQueue = current . updateQueue ;
364
+ workInProgress . firstContextDependency = current . firstContextDependency ;
347
365
348
366
// These will be overridden during the parent's reconciliation
349
367
workInProgress . sibling = current . sibling ;
@@ -556,7 +574,7 @@ export function createFiberFromProfiler(
556
574
// Map of expiration time to interaction events.
557
575
// Populated when state updates are enqueued during a tracked interaction.
558
576
fiber . stateNode = {
559
- committedInteractions : [ ] ,
577
+ committedInteractions : new Set ( ) ,
560
578
pendingInteractionMap,
561
579
} ;
562
580
@@ -633,12 +651,14 @@ export function assignFiberPropertiesInDEV(
633
651
target . memoizedProps = source . memoizedProps ;
634
652
target . updateQueue = source . updateQueue ;
635
653
target . memoizedState = source . memoizedState ;
654
+ target . firstContextDependency = source . firstContextDependency ;
636
655
target . mode = source . mode ;
637
656
target . effectTag = source . effectTag ;
638
657
target . nextEffect = source . nextEffect ;
639
658
target . firstEffect = source . firstEffect ;
640
659
target . lastEffect = source . lastEffect ;
641
660
target . expirationTime = source . expirationTime ;
661
+ target . childExpirationTime = source . childExpirationTime ;
642
662
target . alternate = source . alternate ;
643
663
if ( enableProfilerTimer ) {
644
664
target . actualDuration = source . actualDuration ;
0 commit comments