@@ -23,13 +23,11 @@ describe('ReactShallowRenderer', () => {
2323 React = require ( 'react' ) ;
2424 } ) ;
2525
26- it ( 'should call all of the lifecycle hooks' , ( ) => {
26+ it ( 'should call all of the legacy lifecycle hooks' , ( ) => {
2727 const logs = [ ] ;
2828 const logger = message => ( ) => logs . push ( message ) || true ;
2929
3030 class SomeComponent extends React . Component {
31- state = { } ;
32- static getDerivedStateFromProps = logger ( 'getDerivedStateFromProps' ) ;
3331 UNSAFE_componentWillMount = logger ( 'componentWillMount' ) ;
3432 componentDidMount = logger ( 'componentDidMount' ) ;
3533 UNSAFE_componentWillReceiveProps = logger ( 'componentWillReceiveProps' ) ;
@@ -43,16 +41,11 @@ describe('ReactShallowRenderer', () => {
4341 }
4442
4543 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 } /> ) ;
5245
5346 // Calling cDU might lead to problems with host component references.
5447 // Since our components aren't really mounted, refs won't be available.
55- expect ( logs ) . toEqual ( [ 'getDerivedStateFromProps' , ' componentWillMount'] ) ;
48+ expect ( logs ) . toEqual ( [ 'componentWillMount' ] ) ;
5649
5750 logs . splice ( 0 ) ;
5851
@@ -68,12 +61,75 @@ describe('ReactShallowRenderer', () => {
6861 // The previous shallow renderer did not trigger cDU for props changes.
6962 expect ( logs ) . toEqual ( [
7063 'componentWillReceiveProps' ,
71- 'getDerivedStateFromProps' ,
7264 'shouldComponentUpdate' ,
7365 'componentWillUpdate' ,
7466 ] ) ;
7567 } ) ;
7668
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+
77133 it ( 'should only render 1 level deep' , ( ) => {
78134 function Parent ( ) {
79135 return (
@@ -422,11 +478,10 @@ describe('ReactShallowRenderer', () => {
422478 expect ( result ) . toEqual ( < div /> ) ;
423479 } ) ;
424480
425- it ( 'passes expected params to component lifecycle methods' , ( ) => {
481+ it ( 'passes expected params to legacy component lifecycle methods' , ( ) => {
426482 const componentDidUpdateParams = [ ] ;
427483 const componentWillReceivePropsParams = [ ] ;
428484 const componentWillUpdateParams = [ ] ;
429- const getDerivedStateFromPropsParams = [ ] ;
430485 const setStateParams = [ ] ;
431486 const shouldComponentUpdateParams = [ ] ;
432487
@@ -448,10 +503,6 @@ describe('ReactShallowRenderer', () => {
448503 componentDidUpdate ( ...args ) {
449504 componentDidUpdateParams . push ( ...args ) ;
450505 }
451- static getDerivedStateFromProps ( ...args ) {
452- getDerivedStateFromPropsParams . push ( args ) ;
453- return null ;
454- }
455506 UNSAFE_componentWillReceiveProps ( ...args ) {
456507 componentWillReceivePropsParams . push ( ...args ) ;
457508 this . setState ( ( ...innerArgs ) => {
@@ -472,22 +523,10 @@ describe('ReactShallowRenderer', () => {
472523 }
473524
474525 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 ,
487529 ) ;
488- expect ( getDerivedStateFromPropsParams ) . toEqual ( [
489- [ initialProp , initialState ] ,
490- ] ) ;
491530 expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
492531 expect ( componentWillReceivePropsParams ) . toEqual ( [ ] ) ;
493532 expect ( componentWillUpdateParams ) . toEqual ( [ ] ) ;
@@ -504,10 +543,6 @@ describe('ReactShallowRenderer', () => {
504543 updatedContext ,
505544 ] ) ;
506545 expect ( setStateParams ) . toEqual ( [ initialState , initialProp ] ) ;
507- expect ( getDerivedStateFromPropsParams ) . toEqual ( [
508- [ initialProp , initialState ] ,
509- [ updatedProp , initialState ] ,
510- ] ) ;
511546 expect ( shouldComponentUpdateParams ) . toEqual ( [
512547 updatedProp ,
513548 updatedState ,
@@ -521,6 +556,72 @@ describe('ReactShallowRenderer', () => {
521556 expect ( componentDidUpdateParams ) . toEqual ( [ ] ) ;
522557 } ) ;
523558
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+
524625 it ( 'can shallowly render components with ref as function' , ( ) => {
525626 class SimpleComponent extends React . Component {
526627 state = { clicked : false } ;
0 commit comments