Stop using Scheduler.log to test double invocations (#29008)
Sebastian Silbermann committed
May 20, 2024 at 15:30 UTC
55dd0b1d0e2a17f137579f85016e69782cad7cf7
3 files changed
+322
-213
packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js
+5
-1
@@ -161,7 +161,11 @@ describe('ReactInternalTestUtils', () => {
161
162
const root = ReactNoop.createRoot();
163
await act(() => {
164
- root.render(<App />);
164
+ root.render(
165
+ <React.StrictMode>
166
+ <App />
167
+ </React.StrictMode>
168
+ );
169
});
170
assertLog(['A', 'B', 'C']);
171
});
packages/react-reconciler/src/__tests__/StrictEffectsMode-test.js
+156
-136
@@ -11,33 +11,29 @@
11
12
let React;
13
let ReactNoop;
14
-let Scheduler;
14
let act;
16
-let assertLog;
15
16
describe('StrictEffectsMode', () => {
17
beforeEach(() => {
18
jest.resetModules();
19
act = require('internal-test-utils').act;
22
- const InternalTestUtils = require('internal-test-utils');
23
- assertLog = InternalTestUtils.assertLog;
20
21
React = require('react');
26
- Scheduler = require('scheduler');
22
ReactNoop = require('react-noop-renderer');
23
});
24
25
// @gate !disableLegacyMode
26
it('should not double invoke effects in legacy mode', async () => {
27
+ const log = [];
28
function App({text}) {
29
React.useEffect(() => {
34
- Scheduler.log('useEffect mount');
35
- return () => Scheduler.log('useEffect unmount');
30
+ log.push('useEffect mount');
31
+ return () => log.push('useEffect unmount');
32
});
33
34
React.useLayoutEffect(() => {
39
- Scheduler.log('useLayoutEffect mount');
40
- return () => Scheduler.log('useLayoutEffect unmount');
35
+ log.push('useLayoutEffect mount');
36
+ return () => log.push('useLayoutEffect unmount');
37
});
38
39
return text;
@@ -52,19 +48,20 @@ describe('StrictEffectsMode', () => {
48
);
49
});
50
55
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
51
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
52
});
53
54
it('double invoking for effects works properly', async () => {
55
+ const log = [];
56
function App({text}) {
57
React.useEffect(() => {
61
- Scheduler.log('useEffect mount');
62
- return () => Scheduler.log('useEffect unmount');
58
+ log.push('useEffect mount');
59
+ return () => log.push('useEffect unmount');
60
});
61
62
React.useLayoutEffect(() => {
66
- Scheduler.log('useLayoutEffect mount');
67
- return () => Scheduler.log('useLayoutEffect unmount');
63
+ log.push('useLayoutEffect mount');
64
+ return () => log.push('useLayoutEffect unmount');
65
});
66
67
return text;
@@ -80,7 +77,7 @@ describe('StrictEffectsMode', () => {
77
});
78
79
if (__DEV__) {
83
- assertLog([
80
+ expect(log).toEqual([
81
'useLayoutEffect mount',
82
'useEffect mount',
83
'useLayoutEffect unmount',
@@ -89,9 +86,10 @@ describe('StrictEffectsMode', () => {
86
'useEffect mount',
87
]);
88
} else {
92
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
89
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
90
}
91
92
+ log.length = 0;
93
await act(() => {
94
ReactNoop.renderToRootWithID(
95
<React.StrictMode>
@@ -101,30 +99,32 @@ describe('StrictEffectsMode', () => {
99
);
100
});
101
104
- assertLog([
102
+ expect(log).toEqual([
103
'useLayoutEffect unmount',
104
'useLayoutEffect mount',
105
'useEffect unmount',
106
'useEffect mount',
107
]);
108
109
+ log.length = 0;
110
await act(() => {
111
ReactNoop.unmountRootWithID('root');
112
});
113
115
- assertLog(['useLayoutEffect unmount', 'useEffect unmount']);
114
+ expect(log).toEqual(['useLayoutEffect unmount', 'useEffect unmount']);
115
});
116
117
it('multiple effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
118
+ const log = [];
119
function App({text}) {
120
React.useEffect(() => {
121
- Scheduler.log('useEffect One mount');
122
- return () => Scheduler.log('useEffect One unmount');
121
+ log.push('useEffect One mount');
122
+ return () => log.push('useEffect One unmount');
123
});
124
125
React.useEffect(() => {
126
- Scheduler.log('useEffect Two mount');
127
- return () => Scheduler.log('useEffect Two unmount');
126
+ log.push('useEffect Two mount');
127
+ return () => log.push('useEffect Two unmount');
128
});
129
130
return text;
@@ -140,7 +140,7 @@ describe('StrictEffectsMode', () => {
140
});
141
142
if (__DEV__) {
143
- assertLog([
143
+ expect(log).toEqual([
144
'useEffect One mount',
145
'useEffect Two mount',
146
'useEffect One unmount',
@@ -149,9 +149,10 @@ describe('StrictEffectsMode', () => {
149
'useEffect Two mount',
150
]);
151
} else {
152
- assertLog(['useEffect One mount', 'useEffect Two mount']);
152
+ expect(log).toEqual(['useEffect One mount', 'useEffect Two mount']);
153
}
154
155
+ log.length = 0;
156
await act(() => {
157
ReactNoop.renderToRootWithID(
158
<React.StrictMode>
@@ -161,30 +162,32 @@ describe('StrictEffectsMode', () => {
162
);
163
});
164
164
- assertLog([
165
+ expect(log).toEqual([
166
'useEffect One unmount',
167
'useEffect Two unmount',
168
'useEffect One mount',
169
'useEffect Two mount',
170
]);
171
172
+ log.length = 0;
173
await act(() => {
174
ReactNoop.unmountRootWithID('root');
175
});
176
175
- assertLog(['useEffect One unmount', 'useEffect Two unmount']);
177
+ expect(log).toEqual(['useEffect One unmount', 'useEffect Two unmount']);
178
});
179
180
it('multiple layout effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
181
+ const log = [];
182
function App({text}) {
183
React.useLayoutEffect(() => {
181
- Scheduler.log('useLayoutEffect One mount');
182
- return () => Scheduler.log('useLayoutEffect One unmount');
184
+ log.push('useLayoutEffect One mount');
185
+ return () => log.push('useLayoutEffect One unmount');
186
});
187
188
React.useLayoutEffect(() => {
186
- Scheduler.log('useLayoutEffect Two mount');
187
- return () => Scheduler.log('useLayoutEffect Two unmount');
189
+ log.push('useLayoutEffect Two mount');
190
+ return () => log.push('useLayoutEffect Two unmount');
191
});
192
193
return text;
@@ -200,7 +203,7 @@ describe('StrictEffectsMode', () => {
203
});
204
205
if (__DEV__) {
203
- assertLog([
206
+ expect(log).toEqual([
207
'useLayoutEffect One mount',
208
'useLayoutEffect Two mount',
209
'useLayoutEffect One unmount',
@@ -209,9 +212,13 @@ describe('StrictEffectsMode', () => {
212
'useLayoutEffect Two mount',
213
]);
214
} else {
212
- assertLog(['useLayoutEffect One mount', 'useLayoutEffect Two mount']);
215
+ expect(log).toEqual([
216
+ 'useLayoutEffect One mount',
217
+ 'useLayoutEffect Two mount',
218
+ ]);
219
}
220
221
+ log.length = 0;
222
await act(() => {
223
ReactNoop.renderToRootWithID(
224
<React.StrictMode>
@@ -221,28 +228,33 @@ describe('StrictEffectsMode', () => {
228
);
229
});
230
224
- assertLog([
231
+ expect(log).toEqual([
232
'useLayoutEffect One unmount',
233
'useLayoutEffect Two unmount',
234
'useLayoutEffect One mount',
235
'useLayoutEffect Two mount',
236
]);
237
238
+ log.length = 0;
239
await act(() => {
240
ReactNoop.unmountRootWithID('root');
241
});
242
235
- assertLog(['useLayoutEffect One unmount', 'useLayoutEffect Two unmount']);
243
+ expect(log).toEqual([
244
+ 'useLayoutEffect One unmount',
245
+ 'useLayoutEffect Two unmount',
246
+ ]);
247
});
248
249
it('useEffect and useLayoutEffect is called twice when there is no unmount', async () => {
250
+ const log = [];
251
function App({text}) {
252
React.useEffect(() => {
241
- Scheduler.log('useEffect mount');
253
+ log.push('useEffect mount');
254
});
255
256
React.useLayoutEffect(() => {
245
- Scheduler.log('useLayoutEffect mount');
257
+ log.push('useLayoutEffect mount');
258
});
259
260
return text;
@@ -257,16 +269,17 @@ describe('StrictEffectsMode', () => {
269
});
270
271
if (__DEV__) {
260
- assertLog([
272
+ expect(log).toEqual([
273
'useLayoutEffect mount',
274
'useEffect mount',
275
'useLayoutEffect mount',
276
'useEffect mount',
277
]);
278
} else {
267
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
279
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
280
}
281
282
+ log.length = 0;
283
await act(() => {
284
ReactNoop.renderToRootWithID(
285
<React.StrictMode>
@@ -275,32 +288,34 @@ describe('StrictEffectsMode', () => {
288
);
289
});
290
278
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
291
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
292
293
+ log.length = 0;
294
await act(() => {
295
ReactNoop.unmountRootWithID('root');
296
});
297
284
- assertLog([]);
298
+ expect(log).toEqual([]);
299
});
300
301
it('passes the right context to class component lifecycles', async () => {
302
+ const log = [];
303
class App extends React.PureComponent {
304
test() {}
305
306
componentDidMount() {
307
this.test();
293
- Scheduler.log('componentDidMount');
308
+ log.push('componentDidMount');
309
}
310
311
componentDidUpdate() {
312
this.test();
298
- Scheduler.log('componentDidUpdate');
313
+ log.push('componentDidUpdate');
314
}
315
316
componentWillUnmount() {
317
this.test();
303
- Scheduler.log('componentWillUnmount');
318
+ log.push('componentWillUnmount');
319
}
320
321
render() {
@@ -317,28 +332,29 @@ describe('StrictEffectsMode', () => {
332
});
333
334
if (__DEV__) {
320
- assertLog([
335
+ expect(log).toEqual([
336
'componentDidMount',
337
'componentWillUnmount',
338
'componentDidMount',
339
]);
340
} else {
326
- assertLog(['componentDidMount']);
341
+ expect(log).toEqual(['componentDidMount']);
342
}
343
});
344
345
it('double invoking works for class components', async () => {
346
+ const log = [];
347
class App extends React.PureComponent {
348
componentDidMount() {
333
- Scheduler.log('componentDidMount');
349
+ log.push('componentDidMount');
350
}
351
352
componentDidUpdate() {
337
- Scheduler.log('componentDidUpdate');
353
+ log.push('componentDidUpdate');
354
}
355
356
componentWillUnmount() {
341
- Scheduler.log('componentWillUnmount');
357
+ log.push('componentWillUnmount');
358
}
359
360
render() {
@@ -356,15 +372,16 @@ describe('StrictEffectsMode', () => {
372
});
373
374
if (__DEV__) {
359
- assertLog([
375
+ expect(log).toEqual([
376
'componentDidMount',
377
'componentWillUnmount',
378
'componentDidMount',
379
]);
380
} else {
365
- assertLog(['componentDidMount']);
381
+ expect(log).toEqual(['componentDidMount']);
382
}
383
384
+ log.length = 0;
385
await act(() => {
386
ReactNoop.renderToRootWithID(
387
<React.StrictMode>
@@ -374,23 +391,25 @@ describe('StrictEffectsMode', () => {
391
);
392
});
393
377
- assertLog(['componentDidUpdate']);
394
+ expect(log).toEqual(['componentDidUpdate']);
395
396
+ log.length = 0;
397
await act(() => {
398
ReactNoop.unmountRootWithID('root');
399
});
400
383
- assertLog(['componentWillUnmount']);
401
+ expect(log).toEqual(['componentWillUnmount']);
402
});
403
404
it('invokes componentWillUnmount for class components without componentDidMount', async () => {
405
+ const log = [];
406
class App extends React.PureComponent {
407
componentDidUpdate() {
389
- Scheduler.log('componentDidUpdate');
408
+ log.push('componentDidUpdate');
409
}
410
411
componentWillUnmount() {
393
- Scheduler.log('componentWillUnmount');
412
+ log.push('componentWillUnmount');
413
}
414
415
render() {
@@ -408,11 +427,12 @@ describe('StrictEffectsMode', () => {
427
});
428
429
if (__DEV__) {
411
- assertLog(['componentWillUnmount']);
430
+ expect(log).toEqual(['componentWillUnmount']);
431
} else {
413
- assertLog([]);
432
+ expect(log).toEqual([]);
433
}
434
435
+ log.length = 0;
436
await act(() => {
437
ReactNoop.renderToRootWithID(
438
<React.StrictMode>
@@ -422,28 +442,30 @@ describe('StrictEffectsMode', () => {
442
);
443
});
444
425
- assertLog(['componentDidUpdate']);
445
+ expect(log).toEqual(['componentDidUpdate']);
446
447
+ log.length = 0;
448
await act(() => {
449
ReactNoop.unmountRootWithID('root');
450
});
451
431
- assertLog(['componentWillUnmount']);
452
+ expect(log).toEqual(['componentWillUnmount']);
453
});
454
455
// @gate !disableLegacyMode
456
it('should not double invoke class lifecycles in legacy mode', async () => {
457
+ const log = [];
458
class App extends React.PureComponent {
459
componentDidMount() {
438
- Scheduler.log('componentDidMount');
460
+ log.push('componentDidMount');
461
}
462
463
componentDidUpdate() {
442
- Scheduler.log('componentDidUpdate');
464
+ log.push('componentDidUpdate');
465
}
466
467
componentWillUnmount() {
446
- Scheduler.log('componentWillUnmount');
468
+ log.push('componentWillUnmount');
469
}
470
471
render() {
@@ -460,26 +482,27 @@ describe('StrictEffectsMode', () => {
482
);
483
});
484
463
- assertLog(['componentDidMount']);
485
+ expect(log).toEqual(['componentDidMount']);
486
});
487
488
it('double flushing passive effects only results in one double invoke', async () => {
489
+ const log = [];
490
function App({text}) {
491
const [state, setState] = React.useState(0);
492
React.useEffect(() => {
493
if (state !== 1) {
494
setState(1);
495
}
473
- Scheduler.log('useEffect mount');
474
- return () => Scheduler.log('useEffect unmount');
496
+ log.push('useEffect mount');
497
+ return () => log.push('useEffect unmount');
498
});
499
500
React.useLayoutEffect(() => {
478
- Scheduler.log('useLayoutEffect mount');
479
- return () => Scheduler.log('useLayoutEffect unmount');
501
+ log.push('useLayoutEffect mount');
502
+ return () => log.push('useLayoutEffect unmount');
503
});
504
482
- Scheduler.log(text);
505
+ log.push(text);
506
return text;
507
}
508
@@ -492,7 +515,8 @@ describe('StrictEffectsMode', () => {
515
});
516
517
if (__DEV__) {
495
- assertLog([
518
+ expect(log).toEqual([
519
+ 'mount',
520
'mount',
521
'useLayoutEffect mount',
522
'useEffect mount',
@@ -501,13 +525,14 @@ describe('StrictEffectsMode', () => {
525
'useLayoutEffect mount',
526
'useEffect mount',
527
'mount',
528
+ 'mount',
529
'useLayoutEffect unmount',
530
'useLayoutEffect mount',
531
'useEffect unmount',
532
'useEffect mount',
533
]);
534
} else {
510
- assertLog([
535
+ expect(log).toEqual([
536
'mount',
537
'useLayoutEffect mount',
538
'useEffect mount',
@@ -521,15 +546,16 @@ describe('StrictEffectsMode', () => {
546
});
547
548
it('newly mounted components after initial mount get double invoked', async () => {
549
+ const log = [];
550
let _setShowChild;
551
function Child() {
552
React.useEffect(() => {
527
- Scheduler.log('Child useEffect mount');
528
- return () => Scheduler.log('Child useEffect unmount');
553
+ log.push('Child useEffect mount');
554
+ return () => log.push('Child useEffect unmount');
555
});
556
React.useLayoutEffect(() => {
531
- Scheduler.log('Child useLayoutEffect mount');
532
- return () => Scheduler.log('Child useLayoutEffect unmount');
557
+ log.push('Child useLayoutEffect mount');
558
+ return () => log.push('Child useLayoutEffect unmount');
559
});
560
561
return null;
@@ -539,12 +565,12 @@ describe('StrictEffectsMode', () => {
565
const [showChild, setShowChild] = React.useState(false);
566
_setShowChild = setShowChild;
567
React.useEffect(() => {
542
- Scheduler.log('App useEffect mount');
543
- return () => Scheduler.log('App useEffect unmount');
568
+ log.push('App useEffect mount');
569
+ return () => log.push('App useEffect unmount');
570
});
571
React.useLayoutEffect(() => {
546
- Scheduler.log('App useLayoutEffect mount');
547
- return () => Scheduler.log('App useLayoutEffect unmount');
572
+ log.push('App useLayoutEffect mount');
573
+ return () => log.push('App useLayoutEffect unmount');
574
});
575
576
return showChild && <Child />;
@@ -560,7 +586,7 @@ describe('StrictEffectsMode', () => {
586
});
587
588
if (__DEV__) {
563
- assertLog([
589
+ expect(log).toEqual([
590
'App useLayoutEffect mount',
591
'App useEffect mount',
592
'App useLayoutEffect unmount',
@@ -569,15 +595,16 @@ describe('StrictEffectsMode', () => {
595
'App useEffect mount',
596
]);
597
} else {
572
- assertLog(['App useLayoutEffect mount', 'App useEffect mount']);
598
+ expect(log).toEqual(['App useLayoutEffect mount', 'App useEffect mount']);
599
}
600
601
+ log.length = 0;
602
await act(() => {
603
_setShowChild(true);
604
});
605
606
if (__DEV__) {
580
- assertLog([
607
+ expect(log).toEqual([
608
'App useLayoutEffect unmount',
609
'Child useLayoutEffect mount',
610
'App useLayoutEffect mount',
@@ -590,7 +617,7 @@ describe('StrictEffectsMode', () => {
617
'Child useEffect mount',
618
]);
619
} else {
593
- assertLog([
620
+ expect(log).toEqual([
621
'App useLayoutEffect unmount',
622
'Child useLayoutEffect mount',
623
'App useLayoutEffect mount',
@@ -602,13 +629,14 @@ describe('StrictEffectsMode', () => {
629
});
630
631
it('classes and functions are double invoked together correctly', async () => {
632
+ const log = [];
633
class ClassChild extends React.PureComponent {
634
componentDidMount() {
607
- Scheduler.log('componentDidMount');
635
+ log.push('componentDidMount');
636
}
637
638
componentWillUnmount() {
611
- Scheduler.log('componentWillUnmount');
639
+ log.push('componentWillUnmount');
640
}
641
642
render() {
@@ -618,12 +646,12 @@ describe('StrictEffectsMode', () => {
646
647
function FunctionChild({text}) {
648
React.useEffect(() => {
621
- Scheduler.log('useEffect mount');
622
- return () => Scheduler.log('useEffect unmount');
649
+ log.push('useEffect mount');
650
+ return () => log.push('useEffect unmount');
651
});
652
React.useLayoutEffect(() => {
625
- Scheduler.log('useLayoutEffect mount');
626
- return () => Scheduler.log('useLayoutEffect unmount');
653
+ log.push('useLayoutEffect mount');
654
+ return () => log.push('useLayoutEffect unmount');
655
});
656
return text;
657
}
@@ -647,7 +675,7 @@ describe('StrictEffectsMode', () => {
675
});
676
677
if (__DEV__) {
650
- assertLog([
678
+ expect(log).toEqual([
679
'componentDidMount',
680
'useLayoutEffect mount',
681
'useEffect mount',
@@ -659,13 +687,14 @@ describe('StrictEffectsMode', () => {
687
'useEffect mount',
688
]);
689
} else {
662
- assertLog([
690
+ expect(log).toEqual([
691
'componentDidMount',
692
'useLayoutEffect mount',
693
'useEffect mount',
694
]);
695
}
696
697
+ log.length = 0;
698
await act(() => {
699
ReactNoop.renderToRootWithID(
700
<React.StrictMode>
@@ -675,18 +704,19 @@ describe('StrictEffectsMode', () => {
704
);
705
});
706
678
- assertLog([
707
+ expect(log).toEqual([
708
'useLayoutEffect unmount',
709
'useLayoutEffect mount',
710
'useEffect unmount',
711
'useEffect mount',
712
]);
713
714
+ log.length = 0;
715
await act(() => {
716
ReactNoop.unmountRootWithID('root');
717
});
718
689
- assertLog([
719
+ expect(log).toEqual([
720
'componentWillUnmount',
721
'useLayoutEffect unmount',
722
'useEffect unmount',
@@ -694,9 +724,10 @@ describe('StrictEffectsMode', () => {
724
});
725
726
it('classes without componentDidMount and functions are double invoked together correctly', async () => {
727
+ const log = [];
728
class ClassChild extends React.PureComponent {
729
componentWillUnmount() {
699
- Scheduler.log('componentWillUnmount');
730
+ log.push('componentWillUnmount');
731
}
732
733
render() {
@@ -706,12 +737,12 @@ describe('StrictEffectsMode', () => {
737
738
function FunctionChild({text}) {
739
React.useEffect(() => {
709
- Scheduler.log('useEffect mount');
710
- return () => Scheduler.log('useEffect unmount');
740
+ log.push('useEffect mount');
741
+ return () => log.push('useEffect unmount');
742
});
743
React.useLayoutEffect(() => {
713
- Scheduler.log('useLayoutEffect mount');
714
- return () => Scheduler.log('useLayoutEffect unmount');
744
+ log.push('useLayoutEffect mount');
745
+ return () => log.push('useLayoutEffect unmount');
746
});
747
return text;
748
}
@@ -735,7 +766,7 @@ describe('StrictEffectsMode', () => {
766
});
767
768
if (__DEV__) {
738
- assertLog([
769
+ expect(log).toEqual([
770
'useLayoutEffect mount',
771
'useEffect mount',
772
'componentWillUnmount',
@@ -745,9 +776,10 @@ describe('StrictEffectsMode', () => {
776
'useEffect mount',
777
]);
778
} else {
748
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
779
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
780
}
781
782
+ log.length = 0;
783
await act(() => {
784
ReactNoop.renderToRootWithID(
785
<React.StrictMode>
@@ -757,18 +789,19 @@ describe('StrictEffectsMode', () => {
789
);
790
});
791
760
- assertLog([
792
+ expect(log).toEqual([
793
'useLayoutEffect unmount',
794
'useLayoutEffect mount',
795
'useEffect unmount',
796
'useEffect mount',
797
]);
798
799
+ log.length = 0;
800
await act(() => {
801
ReactNoop.unmountRootWithID('root');
802
});
803
771
- assertLog([
804
+ expect(log).toEqual([
805
'componentWillUnmount',
806
'useLayoutEffect unmount',
807
'useEffect unmount',
@@ -777,7 +810,7 @@ describe('StrictEffectsMode', () => {
810
811
// @gate __DEV__
812
it('should double invoke effects after a re-suspend', async () => {
780
- // Not using Scheduler.log because it silences double render logs.
813
+ // Not using log.push because it silences double render logs.
814
let log = [];
815
let shouldSuspend = true;
816
let resolve;
@@ -867,8 +900,17 @@ describe('StrictEffectsMode', () => {
900
);
901
});
902
903
+ expect(log).toEqual([
904
+ 'Parent rendered',
905
+ 'Parent rendered',
906
+ 'Child rendered',
907
+ 'Child suspended',
908
+ 'Fallback',
909
+ 'Fallback',
910
+ ]);
911
+
912
+ log = [];
913
// while suspended, update
871
- log.push('-----------------------after update');
914
await act(() => {
915
ReactNoop.render(
916
<React.StrictMode>
@@ -877,9 +919,19 @@ describe('StrictEffectsMode', () => {
919
);
920
});
921
880
- // Now resolve and commit
881
- log.push('-----------------------after suspense');
922
+ expect(log).toEqual([
923
+ 'Parent rendered',
924
+ 'Parent rendered',
925
+ 'Child rendered',
926
+ 'Child suspended',
927
+ 'Fallback',
928
+ 'Fallback',
929
+ 'Parent dep destroy',
930
+ 'Parent dep create',
931
+ ]);
932
933
+ log = [];
934
+ // Now resolve and commit
935
await act(() => {
936
resolve();
937
shouldSuspend = false;
@@ -887,22 +939,6 @@ describe('StrictEffectsMode', () => {
939
940
if (gate(flags => flags.useModernStrictMode)) {
941
expect(log).toEqual([
890
- 'Parent rendered',
891
- 'Parent rendered',
892
- 'Child rendered',
893
- 'Child suspended',
894
- 'Fallback',
895
- 'Fallback',
896
- '-----------------------after update',
897
- 'Parent rendered',
898
- 'Parent rendered',
899
- 'Child rendered',
900
- 'Child suspended',
901
- 'Fallback',
902
- 'Fallback',
903
- 'Parent dep destroy',
904
- 'Parent dep create',
905
- '-----------------------after suspense',
942
'Child rendered',
943
'Child rendered',
944
// !!! Committed, destroy and create effect.
@@ -924,22 +960,6 @@ describe('StrictEffectsMode', () => {
960
]);
961
} else {
962
expect(log).toEqual([
927
- 'Parent rendered',
928
- 'Parent rendered',
929
- 'Child rendered',
930
- 'Child suspended',
931
- 'Fallback',
932
- 'Fallback',
933
- '-----------------------after update',
934
- 'Parent rendered',
935
- 'Parent rendered',
936
- 'Child rendered',
937
- 'Child suspended',
938
- 'Fallback',
939
- 'Fallback',
940
- 'Parent dep destroy',
941
- 'Parent dep create',
942
- '-----------------------after suspense',
963
'Child rendered',
964
'Child rendered',
965
'Child dep destroy',
packages/react-reconciler/src/__tests__/StrictEffectsModeDefaults-test.internal.js
+161
-76
@@ -13,7 +13,6 @@ let React;
13
let ReactNoop;
14
let Scheduler;
15
let act;
16
-let assertLog;
16
let waitFor;
17
let waitForAll;
18
let waitForPaint;
@@ -31,20 +30,20 @@ describe('StrictEffectsMode defaults', () => {
30
waitFor = InternalTestUtils.waitFor;
31
waitForAll = InternalTestUtils.waitForAll;
32
waitForPaint = InternalTestUtils.waitForPaint;
34
- assertLog = InternalTestUtils.assertLog;
33
});
34
35
// @gate !disableLegacyMode
36
it('should not double invoke effects in legacy mode', async () => {
37
+ const log = [];
38
function App({text}) {
39
React.useEffect(() => {
41
- Scheduler.log('useEffect mount');
42
- return () => Scheduler.log('useEffect unmount');
40
+ log.push('useEffect mount');
41
+ return () => log.push('useEffect unmount');
42
});
43
44
React.useLayoutEffect(() => {
46
- Scheduler.log('useLayoutEffect mount');
47
- return () => Scheduler.log('useLayoutEffect unmount');
45
+ log.push('useLayoutEffect mount');
46
+ return () => log.push('useLayoutEffect unmount');
47
});
48
49
return text;
@@ -58,22 +57,23 @@ describe('StrictEffectsMode defaults', () => {
57
);
58
});
59
61
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
60
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
61
});
62
63
// @gate !disableLegacyMode
64
it('should not double invoke class lifecycles in legacy mode', async () => {
65
+ const log = [];
66
class App extends React.PureComponent {
67
componentDidMount() {
68
- Scheduler.log('componentDidMount');
68
+ log.push('componentDidMount');
69
}
70
71
componentDidUpdate() {
72
- Scheduler.log('componentDidUpdate');
72
+ log.push('componentDidUpdate');
73
}
74
75
componentWillUnmount() {
76
- Scheduler.log('componentWillUnmount');
76
+ log.push('componentWillUnmount');
77
}
78
79
render() {
@@ -89,15 +89,20 @@ describe('StrictEffectsMode defaults', () => {
89
);
90
});
91
92
- assertLog(['componentDidMount']);
92
+ expect(log).toEqual(['componentDidMount']);
93
});
94
95
if (__DEV__) {
96
it('should flush double-invoked effects within the same frame as layout effects if there are no passive effects', async () => {
97
+ const log = [];
98
function ComponentWithEffects({label}) {
99
React.useLayoutEffect(() => {
100
Scheduler.log(`useLayoutEffect mount "${label}"`);
100
- return () => Scheduler.log(`useLayoutEffect unmount "${label}"`);
101
+ log.push(`useLayoutEffect mount "${label}"`);
102
+ return () => {
103
+ Scheduler.log(`useLayoutEffect unmount "${label}"`);
104
+ log.push(`useLayoutEffect unmount "${label}"`);
105
+ };
106
});
107
108
return label;
@@ -115,8 +120,14 @@ describe('StrictEffectsMode defaults', () => {
120
'useLayoutEffect unmount "one"',
121
'useLayoutEffect mount "one"',
122
]);
123
+ expect(log).toEqual([
124
+ 'useLayoutEffect mount "one"',
125
+ 'useLayoutEffect unmount "one"',
126
+ 'useLayoutEffect mount "one"',
127
+ ]);
128
});
129
130
+ log.length = 0;
131
await act(async () => {
132
ReactNoop.render(
133
<React.StrictMode>
@@ -125,13 +136,23 @@ describe('StrictEffectsMode defaults', () => {
136
</React.StrictMode>,
137
);
138
128
- assertLog([]);
139
+ expect(log).toEqual([]);
140
await waitForPaint([
141
// Cleanup and re-run "one" (and "two") since there is no dependencies array.
142
'useLayoutEffect unmount "one"',
143
'useLayoutEffect mount "one"',
144
'useLayoutEffect mount "two"',
145
146
+ // Since "two" is new, it should be double-invoked.
147
+ 'useLayoutEffect unmount "two"',
148
+ 'useLayoutEffect mount "two"',
149
+ ]);
150
+ expect(log).toEqual([
151
+ // Cleanup and re-run "one" (and "two") since there is no dependencies array.
152
+ 'useLayoutEffect unmount "one"',
153
+ 'useLayoutEffect mount "one"',
154
+ 'useLayoutEffect mount "two"',
155
+
156
// Since "two" is new, it should be double-invoked.
157
'useLayoutEffect unmount "two"',
158
'useLayoutEffect mount "two"',
@@ -142,15 +163,24 @@ describe('StrictEffectsMode defaults', () => {
163
// This test also verifies that double-invoked effects flush synchronously
164
// within the same frame as passive effects.
165
it('should double invoke effects only for newly mounted components', async () => {
166
+ const log = [];
167
function ComponentWithEffects({label}) {
168
React.useEffect(() => {
169
+ log.push(`useEffect mount "${label}"`);
170
Scheduler.log(`useEffect mount "${label}"`);
148
- return () => Scheduler.log(`useEffect unmount "${label}"`);
171
+ return () => {
172
+ log.push(`useEffect unmount "${label}"`);
173
+ Scheduler.log(`useEffect unmount "${label}"`);
174
+ };
175
});
176
177
React.useLayoutEffect(() => {
178
+ log.push(`useLayoutEffect mount "${label}"`);
179
Scheduler.log(`useLayoutEffect mount "${label}"`);
153
- return () => Scheduler.log(`useLayoutEffect unmount "${label}"`);
180
+ return () => {
181
+ log.push(`useLayoutEffect unmount "${label}"`);
182
+ Scheduler.log(`useLayoutEffect unmount "${label}"`);
183
+ };
184
});
185
186
return label;
@@ -171,8 +201,17 @@ describe('StrictEffectsMode defaults', () => {
201
'useLayoutEffect mount "one"',
202
'useEffect mount "one"',
203
]);
204
+ expect(log).toEqual([
205
+ 'useLayoutEffect mount "one"',
206
+ 'useEffect mount "one"',
207
+ 'useLayoutEffect unmount "one"',
208
+ 'useEffect unmount "one"',
209
+ 'useLayoutEffect mount "one"',
210
+ 'useEffect mount "one"',
211
+ ]);
212
});
213
214
+ log.length = 0;
215
await act(async () => {
216
ReactNoop.render(
217
<React.StrictMode>
@@ -187,11 +226,29 @@ describe('StrictEffectsMode defaults', () => {
226
'useLayoutEffect mount "one"',
227
'useLayoutEffect mount "two"',
228
]);
229
+ expect(log).toEqual([
230
+ // Cleanup and re-run "one" (and "two") since there is no dependencies array.
231
+ 'useLayoutEffect unmount "one"',
232
+ 'useLayoutEffect mount "one"',
233
+ 'useLayoutEffect mount "two"',
234
+ ]);
235
+ log.length = 0;
236
await waitForAll([
237
'useEffect unmount "one"',
238
'useEffect mount "one"',
239
'useEffect mount "two"',
240
241
+ // Since "two" is new, it should be double-invoked.
242
+ 'useLayoutEffect unmount "two"',
243
+ 'useEffect unmount "two"',
244
+ 'useLayoutEffect mount "two"',
245
+ 'useEffect mount "two"',
246
+ ]);
247
+ expect(log).toEqual([
248
+ 'useEffect unmount "one"',
249
+ 'useEffect mount "one"',
250
+ 'useEffect mount "two"',
251
+
252
// Since "two" is new, it should be double-invoked.
253
'useLayoutEffect unmount "two"',
254
'useEffect unmount "two"',
@@ -202,15 +259,16 @@ describe('StrictEffectsMode defaults', () => {
259
});
260
261
it('double invoking for effects for modern roots', async () => {
262
+ const log = [];
263
function App({text}) {
264
React.useEffect(() => {
207
- Scheduler.log('useEffect mount');
208
- return () => Scheduler.log('useEffect unmount');
265
+ log.push('useEffect mount');
266
+ return () => log.push('useEffect unmount');
267
});
268
269
React.useLayoutEffect(() => {
212
- Scheduler.log('useLayoutEffect mount');
213
- return () => Scheduler.log('useLayoutEffect unmount');
270
+ log.push('useLayoutEffect mount');
271
+ return () => log.push('useLayoutEffect unmount');
272
});
273
274
return text;
@@ -223,7 +281,7 @@ describe('StrictEffectsMode defaults', () => {
281
);
282
});
283
226
- assertLog([
284
+ expect(log).toEqual([
285
'useLayoutEffect mount',
286
'useEffect mount',
287
'useLayoutEffect unmount',
@@ -232,6 +290,7 @@ describe('StrictEffectsMode defaults', () => {
290
'useEffect mount',
291
]);
292
293
+ log.length = 0;
294
await act(() => {
295
ReactNoop.render(
296
<React.StrictMode>
@@ -240,30 +299,32 @@ describe('StrictEffectsMode defaults', () => {
299
);
300
});
301
243
- assertLog([
302
+ expect(log).toEqual([
303
'useLayoutEffect unmount',
304
'useLayoutEffect mount',
305
'useEffect unmount',
306
'useEffect mount',
307
]);
308
309
+ log.length = 0;
310
await act(() => {
311
ReactNoop.render(null);
312
});
313
254
- assertLog(['useLayoutEffect unmount', 'useEffect unmount']);
314
+ expect(log).toEqual(['useLayoutEffect unmount', 'useEffect unmount']);
315
});
316
317
it('multiple effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
318
+ const log = [];
319
function App({text}) {
320
React.useEffect(() => {
260
- Scheduler.log('useEffect One mount');
261
- return () => Scheduler.log('useEffect One unmount');
321
+ log.push('useEffect One mount');
322
+ return () => log.push('useEffect One unmount');
323
});
324
325
React.useEffect(() => {
265
- Scheduler.log('useEffect Two mount');
266
- return () => Scheduler.log('useEffect Two unmount');
326
+ log.push('useEffect Two mount');
327
+ return () => log.push('useEffect Two unmount');
328
});
329
330
return text;
@@ -277,7 +338,7 @@ describe('StrictEffectsMode defaults', () => {
338
);
339
});
340
280
- assertLog([
341
+ expect(log).toEqual([
342
'useEffect One mount',
343
'useEffect Two mount',
344
'useEffect One unmount',
@@ -286,6 +347,7 @@ describe('StrictEffectsMode defaults', () => {
347
'useEffect Two mount',
348
]);
349
350
+ log.length = 0;
351
await act(() => {
352
ReactNoop.render(
353
<React.StrictMode>
@@ -294,30 +356,32 @@ describe('StrictEffectsMode defaults', () => {
356
);
357
});
358
297
- assertLog([
359
+ expect(log).toEqual([
360
'useEffect One unmount',
361
'useEffect Two unmount',
362
'useEffect One mount',
363
'useEffect Two mount',
364
]);
365
366
+ log.length = 0;
367
await act(() => {
368
ReactNoop.render(null);
369
});
370
308
- assertLog(['useEffect One unmount', 'useEffect Two unmount']);
371
+ expect(log).toEqual(['useEffect One unmount', 'useEffect Two unmount']);
372
});
373
374
it('multiple layout effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
375
+ const log = [];
376
function App({text}) {
377
React.useLayoutEffect(() => {
314
- Scheduler.log('useLayoutEffect One mount');
315
- return () => Scheduler.log('useLayoutEffect One unmount');
378
+ log.push('useLayoutEffect One mount');
379
+ return () => log.push('useLayoutEffect One unmount');
380
});
381
382
React.useLayoutEffect(() => {
319
- Scheduler.log('useLayoutEffect Two mount');
320
- return () => Scheduler.log('useLayoutEffect Two unmount');
383
+ log.push('useLayoutEffect Two mount');
384
+ return () => log.push('useLayoutEffect Two unmount');
385
});
386
387
return text;
@@ -331,7 +395,7 @@ describe('StrictEffectsMode defaults', () => {
395
);
396
});
397
334
- assertLog([
398
+ expect(log).toEqual([
399
'useLayoutEffect One mount',
400
'useLayoutEffect Two mount',
401
'useLayoutEffect One unmount',
@@ -340,6 +404,7 @@ describe('StrictEffectsMode defaults', () => {
404
'useLayoutEffect Two mount',
405
]);
406
407
+ log.length = 0;
408
await act(() => {
409
ReactNoop.render(
410
<React.StrictMode>
@@ -348,28 +413,33 @@ describe('StrictEffectsMode defaults', () => {
413
);
414
});
415
351
- assertLog([
416
+ expect(log).toEqual([
417
'useLayoutEffect One unmount',
418
'useLayoutEffect Two unmount',
419
'useLayoutEffect One mount',
420
'useLayoutEffect Two mount',
421
]);
422
423
+ log.length = 0;
424
await act(() => {
425
ReactNoop.render(null);
426
});
427
362
- assertLog(['useLayoutEffect One unmount', 'useLayoutEffect Two unmount']);
428
+ expect(log).toEqual([
429
+ 'useLayoutEffect One unmount',
430
+ 'useLayoutEffect Two unmount',
431
+ ]);
432
});
433
434
it('useEffect and useLayoutEffect is called twice when there is no unmount', async () => {
435
+ const log = [];
436
function App({text}) {
437
React.useEffect(() => {
368
- Scheduler.log('useEffect mount');
438
+ log.push('useEffect mount');
439
});
440
441
React.useLayoutEffect(() => {
372
- Scheduler.log('useLayoutEffect mount');
442
+ log.push('useLayoutEffect mount');
443
});
444
445
return text;
@@ -383,13 +453,14 @@ describe('StrictEffectsMode defaults', () => {
453
);
454
});
455
386
- assertLog([
456
+ expect(log).toEqual([
457
'useLayoutEffect mount',
458
'useEffect mount',
459
'useLayoutEffect mount',
460
'useEffect mount',
461
]);
462
463
+ log.length = 0;
464
await act(() => {
465
ReactNoop.render(
466
<React.StrictMode>
@@ -398,13 +469,14 @@ describe('StrictEffectsMode defaults', () => {
469
);
470
});
471
401
- assertLog(['useLayoutEffect mount', 'useEffect mount']);
472
+ expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
473
474
+ log.length = 0;
475
await act(() => {
476
ReactNoop.render(null);
477
});
478
407
- assertLog([]);
479
+ expect(log).toEqual([]);
480
});
481
482
//@gate useModernStrictMode
@@ -436,22 +508,23 @@ describe('StrictEffectsMode defaults', () => {
508
});
509
510
it('passes the right context to class component lifecycles', async () => {
511
+ const log = [];
512
class App extends React.PureComponent {
513
test() {}
514
515
componentDidMount() {
516
this.test();
444
- Scheduler.log('componentDidMount');
517
+ log.push('componentDidMount');
518
}
519
520
componentDidUpdate() {
521
this.test();
449
- Scheduler.log('componentDidUpdate');
522
+ log.push('componentDidUpdate');
523
}
524
525
componentWillUnmount() {
526
this.test();
454
- Scheduler.log('componentWillUnmount');
527
+ log.push('componentWillUnmount');
528
}
529
530
render() {
@@ -467,7 +540,7 @@ describe('StrictEffectsMode defaults', () => {
540
);
541
});
542
470
- assertLog([
543
+ expect(log).toEqual([
544
'componentDidMount',
545
'componentWillUnmount',
546
'componentDidMount',
@@ -475,17 +548,18 @@ describe('StrictEffectsMode defaults', () => {
548
});
549
550
it('double invoking works for class components', async () => {
551
+ const log = [];
552
class App extends React.PureComponent {
553
componentDidMount() {
480
- Scheduler.log('componentDidMount');
554
+ log.push('componentDidMount');
555
}
556
557
componentDidUpdate() {
484
- Scheduler.log('componentDidUpdate');
558
+ log.push('componentDidUpdate');
559
}
560
561
componentWillUnmount() {
488
- Scheduler.log('componentWillUnmount');
562
+ log.push('componentWillUnmount');
563
}
564
565
render() {
@@ -501,12 +575,13 @@ describe('StrictEffectsMode defaults', () => {
575
);
576
});
577
504
- assertLog([
578
+ expect(log).toEqual([
579
'componentDidMount',
580
'componentWillUnmount',
581
'componentDidMount',
582
]);
583
584
+ log.length = 0;
585
await act(() => {
586
ReactNoop.render(
587
<React.StrictMode>
@@ -515,35 +590,38 @@ describe('StrictEffectsMode defaults', () => {
590
);
591
});
592
518
- assertLog(['componentDidUpdate']);
593
+ expect(log).toEqual(['componentDidUpdate']);
594
595
+ log.length = 0;
596
await act(() => {
597
ReactNoop.render(null);
598
});
599
524
- assertLog(['componentWillUnmount']);
600
+ expect(log).toEqual(['componentWillUnmount']);
601
});
602
603
it('double flushing passive effects only results in one double invoke', async () => {
604
+ const log = [];
605
function App({text}) {
606
const [state, setState] = React.useState(0);
607
React.useEffect(() => {
608
if (state !== 1) {
609
setState(1);
610
}
534
- Scheduler.log('useEffect mount');
535
- return () => Scheduler.log('useEffect unmount');
611
+ log.push('useEffect mount');
612
+ return () => log.push('useEffect unmount');
613
});
614
615
React.useLayoutEffect(() => {
539
- Scheduler.log('useLayoutEffect mount');
540
- return () => Scheduler.log('useLayoutEffect unmount');
616
+ log.push('useLayoutEffect mount');
617
+ return () => log.push('useLayoutEffect unmount');
618
});
619
543
- Scheduler.log(text);
620
+ log.push(text);
621
return text;
622
}
623
624
+ log.length = 0;
625
await act(() => {
626
ReactNoop.render(
627
<React.StrictMode>
@@ -552,7 +630,8 @@ describe('StrictEffectsMode defaults', () => {
630
);
631
});
632
555
- assertLog([
633
+ expect(log).toEqual([
634
+ 'mount',
635
'mount',
636
'useLayoutEffect mount',
637
'useEffect mount',
@@ -561,6 +640,7 @@ describe('StrictEffectsMode defaults', () => {
640
'useLayoutEffect mount',
641
'useEffect mount',
642
'mount',
643
+ 'mount',
644
'useLayoutEffect unmount',
645
'useLayoutEffect mount',
646
'useEffect unmount',
@@ -570,14 +650,15 @@ describe('StrictEffectsMode defaults', () => {
650
651
it('newly mounted components after initial mount get double invoked', async () => {
652
let _setShowChild;
653
+ const log = [];
654
function Child() {
655
React.useEffect(() => {
575
- Scheduler.log('Child useEffect mount');
576
- return () => Scheduler.log('Child useEffect unmount');
656
+ log.push('Child useEffect mount');
657
+ return () => log.push('Child useEffect unmount');
658
});
659
React.useLayoutEffect(() => {
579
- Scheduler.log('Child useLayoutEffect mount');
580
- return () => Scheduler.log('Child useLayoutEffect unmount');
660
+ log.push('Child useLayoutEffect mount');
661
+ return () => log.push('Child useLayoutEffect unmount');
662
});
663
664
return null;
@@ -587,12 +668,12 @@ describe('StrictEffectsMode defaults', () => {
668
const [showChild, setShowChild] = React.useState(false);
669
_setShowChild = setShowChild;
670
React.useEffect(() => {
590
- Scheduler.log('App useEffect mount');
591
- return () => Scheduler.log('App useEffect unmount');
671
+ log.push('App useEffect mount');
672
+ return () => log.push('App useEffect unmount');
673
});
674
React.useLayoutEffect(() => {
594
- Scheduler.log('App useLayoutEffect mount');
595
- return () => Scheduler.log('App useLayoutEffect unmount');
675
+ log.push('App useLayoutEffect mount');
676
+ return () => log.push('App useLayoutEffect unmount');
677
});
678
679
return showChild && <Child />;
@@ -606,7 +687,7 @@ describe('StrictEffectsMode defaults', () => {
687
);
688
});
689
609
- assertLog([
690
+ expect(log).toEqual([
691
'App useLayoutEffect mount',
692
'App useEffect mount',
693
'App useLayoutEffect unmount',
@@ -615,11 +696,12 @@ describe('StrictEffectsMode defaults', () => {
696
'App useEffect mount',
697
]);
698
699
+ log.length = 0;
700
await act(() => {
701
_setShowChild(true);
702
});
703
622
- assertLog([
704
+ expect(log).toEqual([
705
'App useLayoutEffect unmount',
706
'Child useLayoutEffect mount',
707
'App useLayoutEffect mount',
@@ -634,13 +716,14 @@ describe('StrictEffectsMode defaults', () => {
716
});
717
718
it('classes and functions are double invoked together correctly', async () => {
719
+ const log = [];
720
class ClassChild extends React.PureComponent {
721
componentDidMount() {
639
- Scheduler.log('componentDidMount');
722
+ log.push('componentDidMount');
723
}
724
725
componentWillUnmount() {
643
- Scheduler.log('componentWillUnmount');
726
+ log.push('componentWillUnmount');
727
}
728
729
render() {
@@ -650,12 +733,12 @@ describe('StrictEffectsMode defaults', () => {
733
734
function FunctionChild({text}) {
735
React.useEffect(() => {
653
- Scheduler.log('useEffect mount');
654
- return () => Scheduler.log('useEffect unmount');
736
+ log.push('useEffect mount');
737
+ return () => log.push('useEffect unmount');
738
});
739
React.useLayoutEffect(() => {
657
- Scheduler.log('useLayoutEffect mount');
658
- return () => Scheduler.log('useLayoutEffect unmount');
740
+ log.push('useLayoutEffect mount');
741
+ return () => log.push('useLayoutEffect unmount');
742
});
743
return text;
744
}
@@ -677,7 +760,7 @@ describe('StrictEffectsMode defaults', () => {
760
);
761
});
762
680
- assertLog([
763
+ expect(log).toEqual([
764
'componentDidMount',
765
'useLayoutEffect mount',
766
'useEffect mount',
@@ -689,6 +772,7 @@ describe('StrictEffectsMode defaults', () => {
772
'useEffect mount',
773
]);
774
775
+ log.length = 0;
776
await act(() => {
777
ReactNoop.render(
778
<React.StrictMode>
@@ -697,18 +781,19 @@ describe('StrictEffectsMode defaults', () => {
781
);
782
});
783
700
- assertLog([
784
+ expect(log).toEqual([
785
'useLayoutEffect unmount',
786
'useLayoutEffect mount',
787
'useEffect unmount',
788
'useEffect mount',
789
]);
790
791
+ log.length = 0;
792
await act(() => {
793
ReactNoop.render(null);
794
});
795
711
- assertLog([
796
+ expect(log).toEqual([
797
'componentWillUnmount',
798
'useLayoutEffect unmount',
799
'useEffect unmount',