@@ -65,12 +65,7 @@ import {
6565 reconcileChildFibers ,
6666 cloneChildFibers ,
6767} from './ReactChildFiber' ;
68- import {
69- createUpdate ,
70- enqueueCapturedUpdate ,
71- processUpdateQueue ,
72- ReplaceState ,
73- } from './ReactUpdateQueue' ;
68+ import { processUpdateQueue } from './ReactUpdateQueue' ;
7469import { NoWork , Never } from './ReactFiberExpirationTime' ;
7570import { AsyncMode , StrictMode } from './ReactTypeOfMode' ;
7671import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt' ;
@@ -740,17 +735,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
740735 const nextProps = workInProgress . pendingProps ;
741736 const prevProps = workInProgress . memoizedProps ;
742737
743- // Unless we already captured a promise during this render, reset the
744- // placeholder state back to false. We always attempt to render the real
745- // children before falling back to the placeholder.
746- if ( ( workInProgress . effectTag & DidCapture ) === NoEffect ) {
747- const update = createUpdate ( renderExpirationTime ) ;
748- update . tag = ReplaceState ;
749- update . payload = false ;
750- enqueueCapturedUpdate ( workInProgress , update , renderExpirationTime ) ;
751- }
738+ const prevDidTimeout = workInProgress . memoizedState ;
752739
753- const prevState = workInProgress . memoizedState ;
740+ // The update queue is only used to store expired promises, and to
741+ // schedule a re-render once an expired promise resolves. It does not
742+ // determine whether we should show the placeholder state, because we
743+ // always attempt to show the placeholder state on every render.
754744 const updateQueue = workInProgress . updateQueue ;
755745 if ( updateQueue !== null ) {
756746 processUpdateQueue (
@@ -761,19 +751,24 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
761751 renderExpirationTime ,
762752 ) ;
763753 }
764- const nextState = workInProgress . memoizedState ;
754+
755+ // Check if we already attempted to render the normal state. If we did,
756+ // and we timed out, render the placeholder state.
757+ const alreadyCaptured =
758+ ( workInProgress . effectTag & DidCapture ) === NoEffect ;
759+ const nextDidTimeout = ! alreadyCaptured ;
765760
766761 if ( hasLegacyContextChanged ( ) ) {
767762 // Normally we can bail out on props equality but if context has changed
768763 // we don't do the bailout and we have to reuse existing props instead.
769- } else if ( nextProps === prevProps && nextState === prevState ) {
764+ } else if ( nextProps === prevProps && nextDidTimeout === prevDidTimeout ) {
770765 return bailoutOnAlreadyFinishedWork ( current , workInProgress ) ;
771766 }
772767
773- const didTimeout = nextState ;
774768 const render = nextProps . children ;
775- const nextChildren = render ( didTimeout ) ;
769+ const nextChildren = render ( nextDidTimeout ) ;
776770 workInProgress . memoizedProps = nextProps ;
771+ workInProgress . memoizedState = nextDidTimeout ;
777772 reconcileChildren ( current , workInProgress , nextChildren ) ;
778773 return workInProgress . child ;
779774 } else {
0 commit comments