@@ -605,6 +605,86 @@ describe('ReactFreshIntegration', () => {
605
605
}
606
606
} ) ;
607
607
608
+ it ( 'does not get confused when component is called early' , ( ) => {
609
+ if ( __DEV__ ) {
610
+ render ( `
611
+ // This isn't really a valid pattern but it's close enough
612
+ // to simulate what happens when you call ReactDOM.render
613
+ // in the same file. We want to ensure this doesn't confuse
614
+ // the runtime.
615
+ App();
616
+
617
+ function App() {
618
+ const [x, setX] = useFancyState('X');
619
+ const [y, setY] = useFancyState('Y');
620
+ return <h1>A{x}{y}</h1>;
621
+ };
622
+
623
+ function useFancyState(initialState) {
624
+ // No real Hook calls to avoid triggering invalid call invariant.
625
+ // We only want to verify that we can still call this function early.
626
+ return initialState;
627
+ }
628
+
629
+ export default App;
630
+ ` ) ;
631
+ let el = container . firstChild ;
632
+ expect ( el . textContent ) . toBe ( 'AXY' ) ;
633
+
634
+ patch ( `
635
+ // This isn't really a valid pattern but it's close enough
636
+ // to simulate what happens when you call ReactDOM.render
637
+ // in the same file. We want to ensure this doesn't confuse
638
+ // the runtime.
639
+ App();
640
+
641
+ function App() {
642
+ const [x, setX] = useFancyState('X');
643
+ const [y, setY] = useFancyState('Y');
644
+ return <h1>B{x}{y}</h1>;
645
+ };
646
+
647
+ function useFancyState(initialState) {
648
+ // No real Hook calls to avoid triggering invalid call invariant.
649
+ // We only want to verify that we can still call this function early.
650
+ return initialState;
651
+ }
652
+
653
+ export default App;
654
+ ` ) ;
655
+ // Same state variables, so no remount.
656
+ expect ( container . firstChild ) . toBe ( el ) ;
657
+ expect ( el . textContent ) . toBe ( 'BXY' ) ;
658
+
659
+ patch ( `
660
+ // This isn't really a valid pattern but it's close enough
661
+ // to simulate what happens when you call ReactDOM.render
662
+ // in the same file. We want to ensure this doesn't confuse
663
+ // the runtime.
664
+ App();
665
+
666
+ function App() {
667
+ const [y, setY] = useFancyState('Y');
668
+ const [x, setX] = useFancyState('X');
669
+ return <h1>B{x}{y}</h1>;
670
+ };
671
+
672
+ function useFancyState(initialState) {
673
+ // No real Hook calls to avoid triggering invalid call invariant.
674
+ // We only want to verify that we can still call this function early.
675
+ return initialState;
676
+ }
677
+
678
+ export default App;
679
+ ` ) ;
680
+ // Hooks were re-ordered. This causes a remount.
681
+ // Therefore, Hook calls don't accidentally share state.
682
+ expect ( container . firstChild ) . not . toBe ( el ) ;
683
+ el = container . firstChild ;
684
+ expect ( el . textContent ) . toBe ( 'BXY' ) ;
685
+ }
686
+ } ) ;
687
+
608
688
it ( 'does not get confused by Hooks defined inline' , ( ) => {
609
689
// This is not a recommended pattern but at least it shouldn't break.
610
690
if ( __DEV__ ) {
0 commit comments