11
11
'use strict' ;
12
12
13
13
const React = require ( 'react' ) ;
14
- const createReactClass = require ( 'create-react-class' ) ;
15
14
const ReactNative = require ( 'react-native' ) ;
16
- /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
17
- * found when Flow v0.54 was deployed. To see the error delete this comment and
18
- * run Flow. */
19
- const TimerMixin = require ( 'react-timer-mixin' ) ;
20
-
21
15
const { StyleSheet, Text, View} = ReactNative ;
22
16
const { TestModule} = ReactNative . NativeModules ;
23
17
24
- const TimersTest = createReactClass ( {
25
- displayName : 'TimersTest' ,
26
- mixins : [ TimerMixin ] ,
18
+ type Props = $ReadOnly < { || } > ;
27
19
28
- _nextTest : ( ) => { } ,
29
- _interval : - 1 ,
20
+ type State = { |
21
+ count : number ,
22
+ done : boolean ,
23
+ | } ;
30
24
31
- getInitialState ( ) {
32
- return {
33
- count : 0 ,
34
- done : false ,
35
- } ;
36
- } ,
25
+ type ImmediateID = Object ;
26
+
27
+ class TimersTest extends React . Component < Props , State > {
28
+ _nextTest = ( ) => { } ;
29
+ _interval : ?IntervalID = null ;
30
+
31
+ _timeoutIDs : Set < TimeoutID > = new Set ( ) ;
32
+ _intervalIDs : Set < IntervalID > = new Set ( ) ;
33
+ _immediateIDs : Set < ImmediateID > = new Set ( ) ;
34
+ _animationFrameIDs : Set < AnimationFrameID > = new Set ( ) ;
35
+
36
+ state = {
37
+ count : 0 ,
38
+ done : false ,
39
+ } ;
40
+
41
+ setTimeout ( fn : ( ) = > void , time : number ) : TimeoutID {
42
+ const id = setTimeout ( ( ) => {
43
+ this . _timeoutIDs . delete ( id ) ;
44
+ fn ( ) ;
45
+ } , time ) ;
46
+
47
+ this . _timeoutIDs . add ( id ) ;
48
+
49
+ return id ;
50
+ }
51
+
52
+ clearTimeout ( id : TimeoutID ) {
53
+ this . _timeoutIDs . delete ( id ) ;
54
+ clearTimeout ( id ) ;
55
+ }
56
+
57
+ setInterval ( fn : ( ) => void , time : number ) : IntervalID {
58
+ const id = setInterval ( ( ) => {
59
+ fn ( ) ;
60
+ } , time ) ;
61
+
62
+ this . _intervalIDs . add ( id ) ;
63
+
64
+ return id ;
65
+ }
66
+
67
+ clearInterval ( id : IntervalID ) {
68
+ this . _intervalIDs . delete ( id ) ;
69
+ clearInterval ( id ) ;
70
+ }
71
+
72
+ setImmediate ( fn : ( ) = > void ) : ImmediateID {
73
+ const id = setImmediate ( ( ) => {
74
+ this . _immediateIDs . delete ( id ) ;
75
+ fn ( ) ;
76
+ } ) ;
77
+
78
+ this . _immediateIDs . add ( id ) ;
79
+
80
+ return id ;
81
+ }
82
+
83
+ requestAnimationFrame ( fn : ( ) = > void ) : AnimationFrameID {
84
+ const id = requestAnimationFrame ( ( ) => {
85
+ this . _animationFrameIDs . delete ( id ) ;
86
+ fn ( ) ;
87
+ } ) ;
88
+
89
+ this . _animationFrameIDs . add ( id ) ;
90
+
91
+ return id ;
92
+ }
93
+
94
+ cancelAnimationFrame ( id : AnimationFrameID ) : void {
95
+ this . _animationFrameIDs . delete ( id ) ;
96
+ cancelAnimationFrame ( id ) ;
97
+ }
37
98
38
99
componentDidMount ( ) {
39
100
this . setTimeout ( this . testSetTimeout0 , 1000 ) ;
40
- } ,
101
+ }
41
102
42
103
testSetTimeout0 ( ) {
43
104
this . setTimeout ( this . testSetTimeout1 , 0 ) ;
44
- } ,
105
+ }
45
106
46
107
testSetTimeout1 ( ) {
47
108
this . setTimeout ( this . testSetTimeout50 , 1 ) ;
48
- } ,
109
+ }
49
110
50
111
testSetTimeout50 ( ) {
51
112
this . setTimeout ( this . testRequestAnimationFrame , 50 ) ;
52
- } ,
113
+ }
53
114
54
115
testRequestAnimationFrame ( ) {
55
116
this . requestAnimationFrame ( this . testSetInterval0 ) ;
56
- } ,
117
+ }
57
118
58
119
testSetInterval0 ( ) {
59
120
this . _nextTest = this . testSetInterval20 ;
60
121
this . _interval = this . setInterval ( this . _incrementInterval , 0 ) ;
61
- } ,
122
+ }
62
123
63
124
testSetInterval20 ( ) {
64
125
this . _nextTest = this . testSetImmediate ;
65
126
this . _interval = this . setInterval ( this . _incrementInterval , 20 ) ;
66
- } ,
127
+ }
67
128
68
129
testSetImmediate ( ) {
69
130
this . setImmediate ( this . testClearTimeout0 ) ;
70
- } ,
131
+ }
71
132
72
133
testClearTimeout0 ( ) {
73
134
const timeout = this . setTimeout ( ( ) => this . _fail ( 'testClearTimeout0' ) , 0 ) ;
74
135
this . clearTimeout ( timeout ) ;
75
136
this . testClearTimeout30 ( ) ;
76
- } ,
137
+ }
77
138
78
139
testClearTimeout30 ( ) {
79
140
const timeout = this . setTimeout ( ( ) => this . _fail ( 'testClearTimeout30' ) , 30 ) ;
80
141
this . clearTimeout ( timeout ) ;
81
142
this . setTimeout ( this . testClearMulti , 50 ) ;
82
- } ,
143
+ }
83
144
84
145
testClearMulti ( ) {
85
146
const fails = [ ] ;
@@ -96,7 +157,7 @@ const TimersTest = createReactClass({
96
157
this . setTimeout ( ( ) => this . clearTimeout ( delayClear ) , 20 ) ;
97
158
98
159
this . setTimeout ( this . testOrdering , 50 ) ;
99
- } ,
160
+ }
100
161
101
162
testOrdering ( ) {
102
163
// Clear timers are set first because it's more likely to uncover bugs.
@@ -131,42 +192,73 @@ const TimersTest = createReactClass({
131
192
25 ,
132
193
) ;
133
194
this . setTimeout ( this . done , 50 ) ;
134
- } ,
195
+ }
135
196
136
197
done ( ) {
137
198
this . setState ( { done : true } , ( ) => {
138
199
TestModule . markTestCompleted ( ) ;
139
200
} ) ;
140
- } ,
201
+ }
202
+
203
+ componentWillUnmount ( ) {
204
+ for ( const timeoutID of this . _timeoutIDs ) {
205
+ clearTimeout ( timeoutID ) ;
206
+ }
207
+
208
+ for ( const intervalID of this . _intervalIDs ) {
209
+ clearInterval ( intervalID ) ;
210
+ }
211
+
212
+ for ( const requestAnimationFrameID of this . _animationFrameIDs ) {
213
+ cancelAnimationFrame ( requestAnimationFrameID ) ;
214
+ }
215
+
216
+ for ( const immediateID of this . _immediateIDs ) {
217
+ clearImmediate ( immediateID ) ;
218
+ }
219
+
220
+ this . _timeoutIDs = new Set ( ) ;
221
+ this . _intervalIDs = new Set ( ) ;
222
+ this . _animationFrameIDs = new Set ( ) ;
223
+ this . _immediateIDs = new Set ( ) ;
224
+
225
+ if ( this . _interval != null ) {
226
+ clearInterval ( this . _interval ) ;
227
+ this . _interval = null ;
228
+ }
229
+ }
141
230
142
231
render ( ) {
143
232
return (
144
233
< View style = { styles . container } >
145
234
< Text >
146
- { this . constructor . displayName + ': \n' }
235
+ { this . constructor . name + ': \n' }
147
236
Intervals: { this . state . count + '\n' }
148
237
{ this . state . done ? 'Done' : 'Testing...' }
149
238
</ Text >
150
239
</ View >
151
240
) ;
152
- } ,
241
+ }
153
242
154
243
_incrementInterval ( ) {
155
244
if ( this . state . count > 3 ) {
156
245
throw new Error ( 'interval incremented past end.' ) ;
157
246
}
158
247
if ( this . state . count === 3 ) {
159
- this . clearInterval ( this . _interval ) ;
248
+ if ( this . _interval != null ) {
249
+ this . clearInterval ( this . _interval ) ;
250
+ this . _interval = null ;
251
+ }
160
252
this . setState ( { count : 0 } , this . _nextTest ) ;
161
253
return ;
162
254
}
163
255
this . setState ( { count : this . state . count + 1 } ) ;
164
- } ,
256
+ }
165
257
166
258
_fail ( caller : string ) : void {
167
259
throw new Error ( '_fail called by ' + caller ) ;
168
- } ,
169
- } ) ;
260
+ }
261
+ }
170
262
171
263
const styles = StyleSheet . create ( {
172
264
container : {
@@ -175,6 +267,4 @@ const styles = StyleSheet.create({
175
267
} ,
176
268
} ) ;
177
269
178
- TimersTest . displayName = 'TimersTest' ;
179
-
180
270
module . exports = TimersTest ;
0 commit comments