@@ -30,11 +30,14 @@ import {
30
30
Mode ,
31
31
ContextProvider ,
32
32
ContextConsumer ,
33
+ TimeoutComponent ,
33
34
} from 'shared/ReactTypeOfWork' ;
34
35
import {
36
+ NoEffect ,
35
37
PerformedWork ,
36
38
Placement ,
37
39
ContentReset ,
40
+ DidCapture ,
38
41
Ref ,
39
42
} from 'shared/ReactTypeOfSideEffect' ;
40
43
import { ReactCurrentOwner } from 'shared/ReactGlobalSharedState' ;
@@ -83,8 +86,16 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
83
86
config : HostConfig < T , P , I , TI , HI , PI , C , CC , CX , PL > ,
84
87
hostContext : HostContext < C , CX > ,
85
88
hydrationContext : HydrationContext < C , CX > ,
86
- scheduleWork : ( fiber : Fiber , expirationTime : ExpirationTime ) = > void ,
87
- computeExpirationForFiber : ( fiber : Fiber ) = > ExpirationTime ,
89
+ scheduleWork : (
90
+ fiber : Fiber ,
91
+ startTime : ExpirationTime ,
92
+ expirationTime : ExpirationTime ,
93
+ ) = > void ,
94
+ computeExpirationForFiber : (
95
+ startTime : ExpirationTime ,
96
+ fiber : Fiber ,
97
+ ) = > ExpirationTime ,
98
+ recalculateCurrentTime : ( ) = > ExpirationTime ,
88
99
) {
89
100
const { shouldSetTextContent, shouldDeprioritizeSubtree} = config ;
90
101
@@ -108,6 +119,7 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
108
119
computeExpirationForFiber ,
109
120
memoizeProps ,
110
121
memoizeState ,
122
+ recalculateCurrentTime ,
111
123
) ;
112
124
113
125
// TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
@@ -716,6 +728,57 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
716
728
return workInProgress . stateNode ;
717
729
}
718
730
731
+ function updateTimeoutComponent (
732
+ current ,
733
+ workInProgress ,
734
+ renderExpirationTime ,
735
+ ) {
736
+ const nextProps = workInProgress . pendingProps ;
737
+ const prevProps = workInProgress . memoizedProps ;
738
+
739
+ let nextState = workInProgress . memoizedState ;
740
+ if ( nextState === null ) {
741
+ nextState = workInProgress . memoizedState = false ;
742
+ }
743
+ const prevState = current === null ? nextState : current . memoizedState ;
744
+
745
+ const updateQueue = workInProgress . updateQueue ;
746
+ if ( updateQueue !== null ) {
747
+ nextState = workInProgress . memoizedState = processUpdateQueue (
748
+ current ,
749
+ workInProgress ,
750
+ updateQueue ,
751
+ null ,
752
+ null ,
753
+ renderExpirationTime ,
754
+ ) ;
755
+ }
756
+
757
+ if ( hasLegacyContextChanged ( ) ) {
758
+ // Normally we can bail out on props equality but if context has changed
759
+ // we don't do the bailout and we have to reuse existing props instead.
760
+ } else if (
761
+ // Don't bail out if this is a restart
762
+ ( workInProgress . effectTag & DidCapture ) === NoEffect &&
763
+ prevProps === nextProps &&
764
+ prevState === nextState
765
+ ) {
766
+ return bailoutOnAlreadyFinishedWork ( current , workInProgress ) ;
767
+ }
768
+
769
+ if ( ( workInProgress . effectTag & DidCapture ) !== NoEffect ) {
770
+ nextState = workInProgress . memoizedState = true ;
771
+ }
772
+
773
+ const isExpired = nextState ;
774
+ const render = nextProps . children ;
775
+ const nextChildren = render ( isExpired ) ;
776
+ workInProgress . memoizedProps = nextProps ;
777
+ workInProgress . memoizedState = nextState ;
778
+ reconcileChildren ( current , workInProgress , nextChildren ) ;
779
+ return workInProgress . child ;
780
+ }
781
+
719
782
function updatePortalComponent (
720
783
current ,
721
784
workInProgress ,
@@ -1092,6 +1155,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
1092
1155
// A return component is just a placeholder, we can just run through the
1093
1156
// next one immediately.
1094
1157
return null ;
1158
+ case TimeoutComponent :
1159
+ return updateTimeoutComponent (
1160
+ current ,
1161
+ workInProgress ,
1162
+ renderExpirationTime ,
1163
+ ) ;
1095
1164
case HostPortal :
1096
1165
return updatePortalComponent (
1097
1166
current ,
0 commit comments