@@ -282,6 +282,185 @@ describe('ReactLazy', () => {
282282 expect ( root ) . toMatchRenderedOutput ( 'SiblingB' ) ;
283283 } ) ;
284284
285+ it ( 'sets defaultProps for modern lifecycles' , async ( ) => {
286+ class C extends React . Component {
287+ static defaultProps = { text : 'A' } ;
288+ state = { } ;
289+
290+ static getDerivedStateFromProps ( props ) {
291+ ReactTestRenderer . unstable_yield (
292+ `getDerivedStateFromProps: ${ props . text } ` ,
293+ ) ;
294+ return null ;
295+ }
296+
297+ constructor ( props ) {
298+ super ( props ) ;
299+ ReactTestRenderer . unstable_yield ( `constructor: ${ this . props . text } ` ) ;
300+ }
301+
302+ componentDidMount ( ) {
303+ ReactTestRenderer . unstable_yield (
304+ `componentDidMount: ${ this . props . text } ` ,
305+ ) ;
306+ }
307+
308+ componentDidUpdate ( prevProps ) {
309+ ReactTestRenderer . unstable_yield (
310+ `componentDidUpdate: ${ prevProps . text } -> ${ this . props . text } ` ,
311+ ) ;
312+ }
313+
314+ componentWillUnmount ( ) {
315+ ReactTestRenderer . unstable_yield (
316+ `componentWillUnmount: ${ this . props . text } ` ,
317+ ) ;
318+ }
319+
320+ shouldComponentUpdate ( nextProps ) {
321+ ReactTestRenderer . unstable_yield (
322+ `shouldComponentUpdate: ${ this . props . text } -> ${ nextProps . text } ` ,
323+ ) ;
324+ return true ;
325+ }
326+
327+ getSnapshotBeforeUpdate ( prevProps ) {
328+ ReactTestRenderer . unstable_yield (
329+ `getSnapshotBeforeUpdate: ${ prevProps . text } -> ${ this . props . text } ` ,
330+ ) ;
331+ return null ;
332+ }
333+
334+ render ( ) {
335+ return < Text text = { this . props . text + this . props . num } /> ;
336+ }
337+ }
338+
339+ const LazyClass = lazy ( ( ) => fakeImport ( C ) ) ;
340+
341+ const root = ReactTestRenderer . create (
342+ < Suspense fallback = { < Text text = "Loading..." /> } >
343+ < LazyClass num = { 1 } />
344+ </ Suspense > ,
345+ {
346+ unstable_isConcurrent : true ,
347+ } ,
348+ ) ;
349+
350+ expect ( root ) . toFlushAndYield ( [ 'Loading...' ] ) ;
351+ expect ( root ) . toMatchRenderedOutput ( null ) ;
352+
353+ await Promise . resolve ( ) ;
354+
355+ expect ( root ) . toFlushAndYield ( [
356+ 'constructor: A' ,
357+ 'getDerivedStateFromProps: A' ,
358+ 'A1' ,
359+ 'componentDidMount: A' ,
360+ ] ) ;
361+
362+ root . update (
363+ < Suspense fallback = { < Text text = "Loading..." /> } >
364+ < LazyClass num = { 2 } />
365+ </ Suspense > ,
366+ ) ;
367+ expect ( root ) . toFlushAndYield ( [
368+ 'getDerivedStateFromProps: A' ,
369+ 'shouldComponentUpdate: A -> A' ,
370+ 'A2' ,
371+ 'getSnapshotBeforeUpdate: A -> A' ,
372+ 'componentDidUpdate: A -> A' ,
373+ ] ) ;
374+ expect ( root ) . toMatchRenderedOutput ( 'A2' ) ;
375+
376+ root . update (
377+ < Suspense fallback = { < Text text = "Loading..." /> } >
378+ < LazyClass num = { 3 } />
379+ </ Suspense > ,
380+ ) ;
381+ expect ( root ) . toFlushAndYield ( [
382+ 'getDerivedStateFromProps: A' ,
383+ 'shouldComponentUpdate: A -> A' ,
384+ 'A3' ,
385+ 'getSnapshotBeforeUpdate: A -> A' ,
386+ 'componentDidUpdate: A -> A' ,
387+ ] ) ;
388+ expect ( root ) . toMatchRenderedOutput ( 'A3' ) ;
389+ } ) ;
390+
391+ it ( 'sets defaultProps for legacy lifecycles' , async ( ) => {
392+ class C extends React . Component {
393+ static defaultProps = { text : 'A' } ;
394+ state = { } ;
395+
396+ UNSAFE_componentWillMount ( ) {
397+ ReactTestRenderer . unstable_yield (
398+ `UNSAFE_componentWillMount: ${ this . props . text } ` ,
399+ ) ;
400+ }
401+
402+ UNSAFE_componentWillUpdate ( nextProps ) {
403+ ReactTestRenderer . unstable_yield (
404+ `UNSAFE_componentWillUpdate: ${ this . props . text } -> ${ nextProps . text } ` ,
405+ ) ;
406+ }
407+
408+ UNSAFE_componentWillReceiveProps ( nextProps ) {
409+ ReactTestRenderer . unstable_yield (
410+ `UNSAFE_componentWillReceiveProps: ${ this . props . text } -> ${
411+ nextProps . text
412+ } `,
413+ ) ;
414+ }
415+
416+ render ( ) {
417+ return < Text text = { this . props . text + this . props . num } /> ;
418+ }
419+ }
420+
421+ const LazyClass = lazy ( ( ) => fakeImport ( C ) ) ;
422+
423+ const root = ReactTestRenderer . create (
424+ < Suspense fallback = { < Text text = "Loading..." /> } >
425+ < LazyClass num = { 1 } />
426+ </ Suspense > ,
427+ ) ;
428+
429+ expect ( ReactTestRenderer ) . toHaveYielded ( [ 'Loading...' ] ) ;
430+ expect ( root ) . toFlushAndYield ( [ ] ) ;
431+ expect ( root ) . toMatchRenderedOutput ( 'Loading...' ) ;
432+
433+ await Promise . resolve ( ) ;
434+
435+ root . update (
436+ < Suspense fallback = { < Text text = "Loading..." /> } >
437+ < LazyClass num = { 2 } />
438+ </ Suspense > ,
439+ ) ;
440+ expect ( ReactTestRenderer ) . toHaveYielded ( [
441+ 'UNSAFE_componentWillMount: A' ,
442+ 'A1' ,
443+ 'UNSAFE_componentWillReceiveProps: A -> A' ,
444+ 'UNSAFE_componentWillUpdate: A -> A' ,
445+ 'A2' ,
446+ ] ) ;
447+ expect ( root ) . toFlushAndYield ( [ ] ) ;
448+ expect ( root ) . toMatchRenderedOutput ( 'A2' ) ;
449+
450+ root . update (
451+ < Suspense fallback = { < Text text = "Loading..." /> } >
452+ < LazyClass num = { 3 } />
453+ </ Suspense > ,
454+ ) ;
455+ expect ( ReactTestRenderer ) . toHaveYielded ( [
456+ 'UNSAFE_componentWillReceiveProps: A -> A' ,
457+ 'UNSAFE_componentWillUpdate: A -> A' ,
458+ 'A3' ,
459+ ] ) ;
460+ expect ( root ) . toFlushAndYield ( [ ] ) ;
461+ expect ( root ) . toMatchRenderedOutput ( 'A3' ) ;
462+ } ) ;
463+
285464 it ( 'includes lazy-loaded component in warning stack' , async ( ) => {
286465 const LazyFoo = lazy ( ( ) => {
287466 ReactTestRenderer . unstable_yield ( 'Started loading' ) ;
0 commit comments