@@ -23,13 +23,11 @@ describe('ReactShallowRenderer', () => {
23
23
React = require ( 'react' ) ;
24
24
} ) ;
25
25
26
- it ( 'should call all of the lifecycle hooks' , ( ) => {
26
+ it ( 'should call all of the legacy lifecycle hooks' , ( ) => {
27
27
const logs = [ ] ;
28
28
const logger = message => ( ) => logs . push ( message ) || true ;
29
29
30
30
class SomeComponent extends React . Component {
31
- state = { } ;
32
- static getDerivedStateFromProps = logger ( 'getDerivedStateFromProps' ) ;
33
31
UNSAFE_componentWillMount = logger ( 'componentWillMount' ) ;
34
32
componentDidMount = logger ( 'componentDidMount' ) ;
35
33
UNSAFE_componentWillReceiveProps = logger ( 'componentWillReceiveProps' ) ;
@@ -43,16 +41,11 @@ describe('ReactShallowRenderer', () => {
43
41
}
44
42
45
43
const shallowRenderer = createRenderer ( ) ;
46
-
47
- expect ( ( ) => shallowRenderer . render ( < SomeComponent foo = { 1 } /> ) ) . toWarnDev (
48
- 'Warning: SomeComponent: Defines both componentWillReceiveProps() and static ' +
49
- 'getDerivedStateFromProps() methods. ' +
50
- 'We recommend using only getDerivedStateFromProps().' ,
51
- ) ;
44
+ shallowRenderer . render ( < SomeComponent foo = { 1 } /> ) ;
52
45
53
46
// Calling cDU might lead to problems with host component references.
54
47
// Since our components aren't really mounted, refs won't be available.
55
- expect ( logs ) . toEqual ( [ 'getDerivedStateFromProps' , ' componentWillMount'] ) ;
48
+ expect ( logs ) . toEqual ( [ 'componentWillMount' ] ) ;
56
49
57
50
logs . splice ( 0 ) ;
58
51
@@ -68,12 +61,75 @@ describe('ReactShallowRenderer', () => {
68
61
// The previous shallow renderer did not trigger cDU for props changes.
69
62
expect ( logs ) . toEqual ( [
70
63
'componentWillReceiveProps' ,
71
- 'getDerivedStateFromProps' ,
72
64
'shouldComponentUpdate' ,
73
65
'componentWillUpdate' ,
74
66
] ) ;
75
67
} ) ;
76
68
69
+ it ( 'should call all of the new lifecycle hooks' , ( ) => {
70
+ const logs = [ ] ;
71
+ const logger = message => ( ) => logs . push ( message ) || true ;
72
+
73
+ class SomeComponent extends React . Component {
74
+ state = { } ;
75
+ static getDerivedStateFromProps = logger ( 'getDerivedStateFromProps' ) ;
76
+ componentDidMount = logger ( 'componentDidMount' ) ;
77
+ shouldComponentUpdate = logger ( 'shouldComponentUpdate' ) ;
78
+ componentDidUpdate = logger ( 'componentDidUpdate' ) ;
79
+ componentWillUnmount = logger ( 'componentWillUnmount' ) ;
80
+ render ( ) {
81
+ return < div /> ;
82
+ }
83
+ }
84
+
85
+ const shallowRenderer = createRenderer ( ) ;
86
+ shallowRenderer . render ( < SomeComponent foo = { 1 } /> ) ;
87
+
88
+ // Calling cDU might lead to problems with host component references.
89
+ // Since our components aren't really mounted, refs won't be available.
90
+ expect ( logs ) . toEqual ( [ 'getDerivedStateFromProps' ] ) ;
91
+
92
+ logs . splice ( 0 ) ;
93
+
94
+ const instance = shallowRenderer . getMountedInstance ( ) ;
95
+ instance . setState ( { } ) ;
96
+
97
+ expect ( logs ) . toEqual ( [ 'shouldComponentUpdate' ] ) ;
98
+
99
+ logs . splice ( 0 ) ;
100
+
101
+ shallowRenderer . render ( < SomeComponent foo = { 2 } /> ) ;
102
+
103
+ // The previous shallow renderer did not trigger cDU for props changes.
104
+ expect ( logs ) . toEqual ( [ 'getDerivedStateFromProps' , 'shouldComponentUpdate' ] ) ;
105
+ } ) ;
106
+
107
+ it ( 'should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present' , ( ) => {
108
+ class Component extends React . Component {
109
+ state = { } ;
110
+ static getDerivedStateFromProps ( ) {
111
+ return null ;
112
+ }
113
+ componentWillMount ( ) {
114
+ throw Error ( 'unexpected' ) ;
115
+ }
116
+ componentWillReceiveProps ( ) {
117
+ throw Error ( 'unexpected' ) ;
118
+ }
119
+ componentWillUpdate ( ) {
120
+ throw Error ( 'unexpected' ) ;
121
+ }
122
+ render ( ) {
123
+ return null ;
124
+ }
125
+ }
126
+
127
+ const shallowRenderer = createRenderer ( ) ;
128
+ expect ( ( ) => shallowRenderer . render ( < Component foo = { 2 } /> ) ) . toWarnDev (
129
+ 'Defines both componentWillReceiveProps() and static getDerivedStateFromProps()' ,
130
+ ) ;
131
+ } ) ;
132
+
77
133
it ( 'should only render 1 level deep' , ( ) => {
78
134
function Parent ( ) {
79
135
return (
@@ -422,11 +478,10 @@ describe('ReactShallowRenderer', () => {
422
478
expect ( result ) . toEqual ( < div /> ) ;
423
479
} ) ;
424
480
425
- it ( 'passes expected params to component lifecycle methods' , ( ) => {
481
+ it ( 'passes expected params to legacy component lifecycle methods' , ( ) => {
426
482
const componentDidUpdateParams = [ ] ;
427
483
const componentWillReceivePropsParams = [ ] ;
428
484
const componentWillUpdateParams = [ ] ;
429
- const getDerivedStateFromPropsParams = [ ] ;
430
485
const setStateParams = [ ] ;
431
486
const shouldComponentUpdateParams = [ ] ;
432
487
@@ -448,10 +503,6 @@ describe('ReactShallowRenderer', () => {
448
503
componentDidUpdate ( ...args ) {
449
504
componentDidUpdateParams . push ( ...args ) ;
450
505
}
451
- static getDerivedStateFromProps ( ...args ) {
452
- getDerivedStateFromPropsParams . push ( args ) ;
453
- return null ;
454
- }
455
506
UNSAFE_componentWillReceiveProps ( ...args ) {
456
507
componentWillReceivePropsParams . push ( ...args ) ;
457
508
this . setState ( ( ...innerArgs ) => {
@@ -472,22 +523,10 @@ describe('ReactShallowRenderer', () => {
472
523
}
473
524
474
525
const shallowRenderer = createRenderer ( ) ;
475
-
476
- // The only lifecycle hook that should be invoked on initial render
477
- // Is the static getDerivedStateFromProps() methods
478
- expect ( ( ) =>
479
- shallowRenderer . render (
480
- React . createElement ( SimpleComponent , initialProp ) ,
481
- initialContext ,
482
- ) ,
483
- ) . toWarnDev (
484
- 'SimpleComponent: Defines both componentWillReceiveProps() and static ' +
485
- 'getDerivedStateFromProps() methods. We recommend using ' +
486
- 'only getDerivedStateFromProps().' ,
526
+ shallowRenderer . render (
527
+ React . createElement ( SimpleComponent , initialProp ) ,
528
+ initialContext ,
487
529
) ;
488
- expect ( getDerivedStateFromPropsParams ) . toEqual ( [
489
- [ initialProp , initialState ] ,
490
- ] ) ;
491
530
expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
492
531
expect ( componentWillReceivePropsParams ) . toEqual ( [ ] ) ;
493
532
expect ( componentWillUpdateParams ) . toEqual ( [ ] ) ;
@@ -504,10 +543,6 @@ describe('ReactShallowRenderer', () => {
504
543
updatedContext ,
505
544
] ) ;
506
545
expect ( setStateParams ) . toEqual ( [ initialState , initialProp ] ) ;
507
- expect ( getDerivedStateFromPropsParams ) . toEqual ( [
508
- [ initialProp , initialState ] ,
509
- [ updatedProp , initialState ] ,
510
- ] ) ;
511
546
expect ( shouldComponentUpdateParams ) . toEqual ( [
512
547
updatedProp ,
513
548
updatedState ,
@@ -521,6 +556,72 @@ describe('ReactShallowRenderer', () => {
521
556
expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
522
557
} ) ;
523
558
559
+ it ( 'passes expected params to new component lifecycle methods' , ( ) => {
560
+ const componentDidUpdateParams = [ ] ;
561
+ const getDerivedStateFromPropsParams = [ ] ;
562
+ const shouldComponentUpdateParams = [ ] ;
563
+
564
+ const initialProp = { prop : 'init prop' } ;
565
+ const initialState = { state : 'init state' } ;
566
+ const initialContext = { context : 'init context' } ;
567
+ const updatedProp = { prop : 'updated prop' } ;
568
+ const updatedContext = { context : 'updated context' } ;
569
+
570
+ class SimpleComponent extends React . Component {
571
+ constructor ( props , context ) {
572
+ super ( props , context ) ;
573
+ this . state = initialState ;
574
+ }
575
+ static contextTypes = {
576
+ context : PropTypes . string ,
577
+ } ;
578
+ componentDidUpdate ( ...args ) {
579
+ componentDidUpdateParams . push ( ...args ) ;
580
+ }
581
+ static getDerivedStateFromProps ( ...args ) {
582
+ getDerivedStateFromPropsParams . push ( args ) ;
583
+ return null ;
584
+ }
585
+ shouldComponentUpdate ( ...args ) {
586
+ shouldComponentUpdateParams . push ( ...args ) ;
587
+ return true ;
588
+ }
589
+ render ( ) {
590
+ return null ;
591
+ }
592
+ }
593
+
594
+ const shallowRenderer = createRenderer ( ) ;
595
+
596
+ // The only lifecycle hook that should be invoked on initial render
597
+ // Is the static getDerivedStateFromProps() methods
598
+ shallowRenderer . render (
599
+ React . createElement ( SimpleComponent , initialProp ) ,
600
+ initialContext ,
601
+ ) ;
602
+ expect ( getDerivedStateFromPropsParams ) . toEqual ( [
603
+ [ initialProp , initialState ] ,
604
+ ] ) ;
605
+ expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
606
+ expect ( shouldComponentUpdateParams ) . toEqual ( [ ] ) ;
607
+
608
+ // Lifecycle hooks should be invoked with the correct prev/next params on update.
609
+ shallowRenderer . render (
610
+ React . createElement ( SimpleComponent , updatedProp ) ,
611
+ updatedContext ,
612
+ ) ;
613
+ expect ( getDerivedStateFromPropsParams ) . toEqual ( [
614
+ [ initialProp , initialState ] ,
615
+ [ updatedProp , initialState ] ,
616
+ ] ) ;
617
+ expect ( shouldComponentUpdateParams ) . toEqual ( [
618
+ updatedProp ,
619
+ initialState ,
620
+ updatedContext ,
621
+ ] ) ;
622
+ expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
623
+ } ) ;
624
+
524
625
it ( 'can shallowly render components with ref as function' , ( ) => {
525
626
class SimpleComponent extends React . Component {
526
627
state = { clicked : false } ;
0 commit comments