@@ -59,6 +59,7 @@ export type UpdateQueue = {
59
59
first : Update | null ,
60
60
last : Update | null ,
61
61
hasForceUpdate : boolean ,
62
+ callbackList : null | Array < Callback > ,
62
63
63
64
// Dev only
64
65
isProcessing ? : boolean ,
@@ -95,13 +96,15 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
95
96
first : null ,
96
97
last : null ,
97
98
hasForceUpdate : false ,
99
+ callbackList : null ,
98
100
isProcessing : false ,
99
101
} ;
100
102
} else {
101
103
queue = {
102
104
first : null ,
103
105
last : null ,
104
106
hasForceUpdate : false ,
107
+ callbackList : null ,
105
108
} ;
106
109
}
107
110
@@ -110,19 +113,25 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
110
113
}
111
114
112
115
// Clones an update queue from a source fiber onto its alternate.
113
- function cloneUpdateQueue ( alt : Fiber , fiber : Fiber ) : UpdateQueue | null {
114
- const sourceQueue = fiber . updateQueue ;
115
- if ( ! sourceQueue ) {
116
+ function cloneUpdateQueue ( current : Fiber , workInProgress : Fiber ) : UpdateQueue | null {
117
+ const currentQueue = current . updateQueue ;
118
+ if ( ! currentQueue ) {
116
119
// The source fiber does not have an update queue.
117
- alt . updateQueue = null ;
120
+ workInProgress . updateQueue = null ;
118
121
return null ;
119
122
}
120
123
// If the alternate already has a queue, reuse the previous object.
121
- const altQueue = alt . updateQueue || { } ;
122
- altQueue . first = sourceQueue . first ;
123
- altQueue . last = sourceQueue . last ;
124
- altQueue . hasForceUpdate = sourceQueue . hasForceUpdate ;
125
- alt . updateQueue = altQueue ;
124
+ const altQueue = workInProgress . updateQueue || { } ;
125
+ altQueue . first = currentQueue . first ;
126
+ altQueue . last = currentQueue . last ;
127
+
128
+ // These fields are invalid by the time we clone from current. Reset them.
129
+ altQueue . hasForceUpdate = false ;
130
+ altQueue . callbackList = null ;
131
+ altQueue . isProcessing = false ;
132
+
133
+ workInProgress . updateQueue = altQueue ;
134
+
126
135
return altQueue ;
127
136
}
128
137
exports . cloneUpdateQueue = cloneUpdateQueue ;
@@ -438,29 +447,20 @@ function beginUpdateQueue(
438
447
// Second condition ignores top-level unmount callbacks if they are not the
439
448
// last update in the queue, since a subsequent update will cause a remount.
440
449
if ( update . callback && ! ( update . isTopLevelUnmount && update . next ) ) {
441
- const callbackUpdate = cloneUpdate ( update ) ;
442
- if ( callbackList && callbackList . last ) {
443
- callbackList . last . next = callbackUpdate ;
444
- callbackList . last = callbackUpdate ;
445
- } else {
446
- callbackList = {
447
- first : callbackUpdate ,
448
- last : callbackUpdate ,
449
- hasForceUpdate : false ,
450
- } ;
451
- }
450
+ callbackList = callbackList || [ ] ;
451
+ callbackList . push ( update . callback ) ;
452
452
workInProgress . effectTag |= CallbackEffect ;
453
453
}
454
454
update = update . next ;
455
455
}
456
456
457
- if ( ! queue . first && ! queue . hasForceUpdate ) {
458
- // Queue is now empty
457
+ queue . callbackList = callbackList ;
458
+
459
+ if ( ! queue . first && ! callbackList && ! queue . hasForceUpdate ) {
460
+ // The queue is empty and there are no callbacks. We can reset it.
459
461
workInProgress . updateQueue = null ;
460
462
}
461
463
462
- workInProgress . callbackList = callbackList ;
463
-
464
464
if ( __DEV__ ) {
465
465
queue . isProcessing = false ;
466
466
}
@@ -469,19 +469,14 @@ function beginUpdateQueue(
469
469
}
470
470
exports . beginUpdateQueue = beginUpdateQueue ;
471
471
472
- function commitCallbacks ( finishedWork : Fiber , callbackList : UpdateQueue , context : mixed ) {
473
- const stopAfter = callbackList . last ;
474
- let update = callbackList . first ;
475
- while ( update ) {
476
- const callback = update . callback ;
477
- if ( typeof callback === 'function' ) {
478
- callback . call ( context ) ;
479
- }
480
- if ( update === stopAfter ) {
481
- break ;
482
- }
483
- update = update . next ;
472
+ function commitCallbacks ( finishedWork : Fiber , queue : UpdateQueue , context : mixed ) {
473
+ const callbackList = queue . callbackList ;
474
+ if ( ! callbackList ) {
475
+ return ;
476
+ }
477
+ for ( let i = 0 ; i < callbackList . length ; i ++ ) {
478
+ const callback = callbackList [ i ] ;
479
+ callback . call ( context ) ;
484
480
}
485
- finishedWork . callbackList = null ;
486
481
}
487
482
exports . commitCallbacks = commitCallbacks ;
0 commit comments