@@ -35,10 +35,12 @@ import {
3535 ContextConsumer ,
3636} from 'shared/ReactTypeOfWork' ;
3737import {
38+ NoEffect ,
3839 PerformedWork ,
3940 Placement ,
4041 ContentReset ,
4142 Ref ,
43+ DidCapture ,
4244} from 'shared/ReactTypeOfSideEffect' ;
4345import { ReactCurrentOwner } from 'shared/ReactGlobalSharedState' ;
4446import {
@@ -58,7 +60,12 @@ import {
5860 reconcileChildFibers ,
5961 cloneChildFibers ,
6062} from './ReactChildFiber' ;
61- import { processUpdateQueue } from './ReactFiberUpdateQueue' ;
63+ import {
64+ createDeriveStateFromPropsUpdate ,
65+ enqueueRenderPhaseUpdate ,
66+ processClassUpdateQueue ,
67+ processRootUpdateQueue ,
68+ } from './ReactUpdateQueue' ;
6269import { NoWork , Never } from './ReactFiberExpirationTime' ;
6370import { AsyncMode , StrictMode } from './ReactTypeOfMode' ;
6471import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt' ;
@@ -105,7 +112,6 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
105112
106113 const {
107114 adoptClassInstance,
108- callGetDerivedStateFromProps,
109115 constructClassInstance,
110116 mountClassInstance,
111117 resumeMountClassInstance,
@@ -260,7 +266,11 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
260266 if ( current === null ) {
261267 if ( workInProgress . stateNode === null ) {
262268 // In the initial pass we might need to construct the instance.
263- constructClassInstance ( workInProgress , workInProgress . pendingProps ) ;
269+ constructClassInstance (
270+ workInProgress ,
271+ workInProgress . pendingProps ,
272+ renderExpirationTime ,
273+ ) ;
264274 mountClassInstance ( workInProgress , renderExpirationTime ) ;
265275
266276 shouldUpdate = true ;
@@ -278,22 +288,11 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
278288 renderExpirationTime ,
279289 ) ;
280290 }
281-
282- // We processed the update queue inside updateClassInstance. It may have
283- // included some errors that were dispatched during the commit phase.
284- // TODO: Refactor class components so this is less awkward.
285- let didCaptureError = false ;
286- const updateQueue = workInProgress . updateQueue ;
287- if ( updateQueue !== null && updateQueue . capturedValues !== null ) {
288- shouldUpdate = true ;
289- didCaptureError = true ;
290- }
291291 return finishClassComponent (
292292 current ,
293293 workInProgress ,
294294 shouldUpdate ,
295295 hasContext ,
296- didCaptureError ,
297296 renderExpirationTime ,
298297 ) ;
299298 }
@@ -303,12 +302,14 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
303302 workInProgress : Fiber ,
304303 shouldUpdate : boolean ,
305304 hasContext : boolean ,
306- didCaptureError : boolean ,
307305 renderExpirationTime : ExpirationTime ,
308306 ) {
309307 // Refs should update even if shouldComponentUpdate returns false
310308 markRef ( current , workInProgress ) ;
311309
310+ const didCaptureError =
311+ ( workInProgress . effectTag & DidCapture ) !== NoEffect ;
312+
312313 if ( ! shouldUpdate && ! didCaptureError ) {
313314 // Context providers should defer to sCU for rendering
314315 if ( hasContext ) {
@@ -413,29 +414,15 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
413414 pushHostRootContext ( workInProgress ) ;
414415 let updateQueue = workInProgress . updateQueue ;
415416 if ( updateQueue !== null ) {
416- const prevState = workInProgress . memoizedState ;
417- const state = processUpdateQueue (
418- current ,
419- workInProgress ,
420- updateQueue ,
421- null ,
422- null ,
423- renderExpirationTime ,
424- ) ;
425- memoizeState ( workInProgress , state ) ;
426- updateQueue = workInProgress . updateQueue ;
427-
428- let element ;
429- if ( updateQueue !== null && updateQueue . capturedValues !== null ) {
430- // There's an uncaught error. Unmount the whole root.
431- element = null ;
432- } else if ( prevState === state ) {
417+ const prevChildren = workInProgress . memoizedState ;
418+ processRootUpdateQueue ( workInProgress , updateQueue , renderExpirationTime ) ;
419+ const nextChildren = workInProgress . memoizedState ;
420+
421+ if ( nextChildren === prevChildren ) {
433422 // If the state is the same as before, that's a bailout because we had
434423 // no work that expires at this time.
435424 resetHydrationState ( ) ;
436425 return bailoutOnAlreadyFinishedWork ( current , workInProgress ) ;
437- } else {
438- element = state . element ;
439426 }
440427 const root : FiberRoot = workInProgress . stateNode ;
441428 if (
@@ -460,16 +447,15 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
460447 workInProgress . child = mountChildFibers (
461448 workInProgress ,
462449 null ,
463- element ,
450+ nextChildren ,
464451 renderExpirationTime ,
465452 ) ;
466453 } else {
467454 // Otherwise reset hydration state in case we aborted and resumed another
468455 // root.
469456 resetHydrationState ( ) ;
470- reconcileChildren ( current , workInProgress , element ) ;
457+ reconcileChildren ( current , workInProgress , nextChildren ) ;
471458 }
472- memoizeState ( workInProgress , state ) ;
473459 return workInProgress . child ;
474460 }
475461 resetHydrationState ( ) ;
@@ -607,19 +593,16 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
607593 workInProgress . memoizedState =
608594 value . state !== null && value . state !== undefined ? value . state : null ;
609595
610- if ( typeof Component . getDerivedStateFromProps === 'function' ) {
611- const partialState = callGetDerivedStateFromProps (
612- workInProgress ,
613- value ,
614- props ,
615- workInProgress . memoizedState ,
616- ) ;
617-
618- if ( partialState !== null && partialState !== undefined ) {
619- workInProgress . memoizedState = Object . assign (
620- { } ,
621- workInProgress . memoizedState ,
622- partialState ,
596+ const getDerivedStateFromProps = Component . getDerivedStateFromProps ;
597+ if ( typeof getDerivedStateFromProps === 'function' ) {
598+ const update = createDeriveStateFromPropsUpdate ( renderExpirationTime ) ;
599+ enqueueRenderPhaseUpdate ( workInProgress , update , renderExpirationTime ) ;
600+ const updateQueue = workInProgress . updateQueue ;
601+ if ( updateQueue !== null ) {
602+ processClassUpdateQueue (
603+ workInProgress ,
604+ updateQueue ,
605+ renderExpirationTime ,
623606 ) ;
624607 }
625608 }
@@ -635,7 +618,6 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
635618 workInProgress ,
636619 true ,
637620 hasContext ,
638- false ,
639621 renderExpirationTime ,
640622 ) ;
641623 } else {
@@ -1098,7 +1080,7 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
10981080 function memoizeState(workInProgress: Fiber, nextState: any) {
10991081 workInProgress . memoizedState = nextState ;
11001082 // Don't reset the updateQueue, in case there are pending updates. Resetting
1101- // is handled by processUpdateQueue .
1083+ // is handled by processClassUpdateQueue .
11021084 }
11031085
11041086 function beginWork(
0 commit comments