@@ -339,6 +339,42 @@ describe('ReactHooksWithNoopRenderer', () => {
339339 ) ;
340340 } ) ;
341341
342+ it ( 'dedupes the warning by component name' , ( ) => {
343+ let _updateCountA ;
344+ function CounterA ( props , ref ) {
345+ const [ , updateCount ] = useState ( 0 ) ;
346+ _updateCountA = updateCount ;
347+ return null ;
348+ }
349+ let _updateCountB ;
350+ function CounterB ( props , ref ) {
351+ const [ , updateCount ] = useState ( 0 ) ;
352+ _updateCountB = updateCount ;
353+ return null ;
354+ }
355+
356+ ReactNoop . render ( [ < CounterA key = "A" /> , < CounterB key = "B" /> ] ) ;
357+ expect ( Scheduler ) . toFlushWithoutYielding ( ) ;
358+ ReactNoop . render ( null ) ;
359+ expect ( Scheduler ) . toFlushWithoutYielding ( ) ;
360+ expect ( ( ) => act ( ( ) => _updateCountA ( 1 ) ) ) . toErrorDev (
361+ "Warning: Can't perform a React state update on an unmounted " +
362+ 'component. This is a no-op, but it indicates a memory leak in your ' +
363+ 'application. To fix, cancel all subscriptions and asynchronous ' +
364+ 'tasks in a useEffect cleanup function.\n' +
365+ ' in CounterA (at **)' ,
366+ ) ;
367+ // already cached so this logs no error
368+ act ( ( ) => _updateCountA ( 2 ) ) ;
369+ expect ( ( ) => act ( ( ) => _updateCountB ( 1 ) ) ) . toErrorDev (
370+ "Warning: Can't perform a React state update on an unmounted " +
371+ 'component. This is a no-op, but it indicates a memory leak in your ' +
372+ 'application. To fix, cancel all subscriptions and asynchronous ' +
373+ 'tasks in a useEffect cleanup function.\n' +
374+ ' in CounterB (at **)' ,
375+ ) ;
376+ } ) ;
377+
342378 it ( 'works with memo' , ( ) => {
343379 let _updateCount ;
344380 function Counter ( props ) {
0 commit comments