@@ -59,6 +59,7 @@ export type UpdateQueue = {
5959 first : Update | null ,
6060 last : Update | null ,
6161 hasForceUpdate : boolean ,
62+ callbackList : null | Array < Callback > ,
6263
6364 // Dev only
6465 isProcessing ? : boolean ,
@@ -95,13 +96,15 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
9596 first : null ,
9697 last : null ,
9798 hasForceUpdate : false ,
99+ callbackList : null ,
98100 isProcessing : false ,
99101 } ;
100102 } else {
101103 queue = {
102104 first : null ,
103105 last : null ,
104106 hasForceUpdate : false ,
107+ callbackList : null ,
105108 } ;
106109 }
107110
@@ -110,19 +113,25 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
110113}
111114
112115// 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 ) {
116119 // The source fiber does not have an update queue.
117- alt . updateQueue = null ;
120+ workInProgress . updateQueue = null ;
118121 return null ;
119122 }
120123 // 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+
126135 return altQueue ;
127136}
128137exports . cloneUpdateQueue = cloneUpdateQueue ;
@@ -438,29 +447,20 @@ function beginUpdateQueue(
438447 // Second condition ignores top-level unmount callbacks if they are not the
439448 // last update in the queue, since a subsequent update will cause a remount.
440449 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 ) ;
452452 workInProgress . effectTag |= CallbackEffect ;
453453 }
454454 update = update . next ;
455455 }
456456
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.
459461 workInProgress . updateQueue = null ;
460462 }
461463
462- workInProgress . callbackList = callbackList ;
463-
464464 if ( __DEV__ ) {
465465 queue . isProcessing = false ;
466466 }
@@ -469,19 +469,14 @@ function beginUpdateQueue(
469469}
470470exports . beginUpdateQueue = beginUpdateQueue ;
471471
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 ) ;
484480 }
485- finishedWork . callbackList = null ;
486481}
487482exports . commitCallbacks = commitCallbacks ;
0 commit comments