@@ -699,6 +699,242 @@ describe('ReactFresh', () => {
699
699
}
700
700
} ) ;
701
701
702
+ it ( 'can remount when change function to memo' , async ( ) => {
703
+ if ( __DEV__ ) {
704
+ await act ( async ( ) => {
705
+ await render ( ( ) => {
706
+ function Test ( ) {
707
+ return < p > hi test</ p > ;
708
+ }
709
+ $RefreshReg$ ( Test , 'Test' ) ;
710
+ return Test ;
711
+ } ) ;
712
+ } ) ;
713
+
714
+ // Check the initial render
715
+ const el = container . firstChild ;
716
+ expect ( el . textContent ) . toBe ( 'hi test' ) ;
717
+
718
+ // Patch to change function to memo
719
+ await act ( async ( ) => {
720
+ await patch ( ( ) => {
721
+ function Test2 ( ) {
722
+ return < p > hi memo</ p > ;
723
+ }
724
+ const Test = React . memo ( Test2 ) ;
725
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
726
+ $RefreshReg$ ( Test , 'Test' ) ;
727
+ return Test ;
728
+ } ) ;
729
+ } ) ;
730
+
731
+ // Check remount
732
+ expect ( container . firstChild ) . not . toBe ( el ) ;
733
+ const nextEl = container . firstChild ;
734
+ expect ( nextEl . textContent ) . toBe ( 'hi memo' ) ;
735
+
736
+ // Patch back to original function
737
+ await act ( async ( ) => {
738
+ await patch ( ( ) => {
739
+ function Test ( ) {
740
+ return < p > hi test</ p > ;
741
+ }
742
+ $RefreshReg$ ( Test , 'Test' ) ;
743
+ return Test ;
744
+ } ) ;
745
+ } ) ;
746
+
747
+ // Check final remount
748
+ expect ( container . firstChild ) . not . toBe ( nextEl ) ;
749
+ const newEl = container . firstChild ;
750
+ expect ( newEl . textContent ) . toBe ( 'hi test' ) ;
751
+ }
752
+ } ) ;
753
+
754
+ it ( 'can remount when change memo to forwardRef' , async ( ) => {
755
+ if ( __DEV__ ) {
756
+ await act ( async ( ) => {
757
+ await render ( ( ) => {
758
+ function Test2 ( ) {
759
+ return < p > hi memo</ p > ;
760
+ }
761
+ const Test = React . memo ( Test2 ) ;
762
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
763
+ $RefreshReg$ ( Test , 'Test' ) ;
764
+ return Test ;
765
+ } ) ;
766
+ } ) ;
767
+ // Check the initial render
768
+ const el = container . firstChild ;
769
+ expect ( el . textContent ) . toBe ( 'hi memo' ) ;
770
+
771
+ // Patch to change memo to forwardRef
772
+ await act ( async ( ) => {
773
+ await patch ( ( ) => {
774
+ function Test2 ( ) {
775
+ return < p > hi forwardRef</ p > ;
776
+ }
777
+ const Test = React . forwardRef ( Test2 ) ;
778
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
779
+ $RefreshReg$ ( Test , 'Test' ) ;
780
+ return Test ;
781
+ } ) ;
782
+ } ) ;
783
+ // Check remount
784
+ expect ( container . firstChild ) . not . toBe ( el ) ;
785
+ const nextEl = container . firstChild ;
786
+ expect ( nextEl . textContent ) . toBe ( 'hi forwardRef' ) ;
787
+
788
+ // Patch back to memo
789
+ await act ( async ( ) => {
790
+ await patch ( ( ) => {
791
+ function Test2 ( ) {
792
+ return < p > hi memo</ p > ;
793
+ }
794
+ const Test = React . memo ( Test2 ) ;
795
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
796
+ $RefreshReg$ ( Test , 'Test' ) ;
797
+ return Test ;
798
+ } ) ;
799
+ } ) ;
800
+ // Check final remount
801
+ expect ( container . firstChild ) . not . toBe ( nextEl ) ;
802
+ const newEl = container . firstChild ;
803
+ expect ( newEl . textContent ) . toBe ( 'hi memo' ) ;
804
+ }
805
+ } ) ;
806
+
807
+ it ( 'can remount when change function to forwardRef' , async ( ) => {
808
+ if ( __DEV__ ) {
809
+ await act ( async ( ) => {
810
+ await render ( ( ) => {
811
+ function Test ( ) {
812
+ return < p > hi test</ p > ;
813
+ }
814
+ $RefreshReg$ ( Test , 'Test' ) ;
815
+ return Test ;
816
+ } ) ;
817
+ } ) ;
818
+
819
+ // Check the initial render
820
+ const el = container . firstChild ;
821
+ expect ( el . textContent ) . toBe ( 'hi test' ) ;
822
+
823
+ // Patch to change function to forwardRef
824
+ await act ( async ( ) => {
825
+ await patch ( ( ) => {
826
+ function Test2 ( ) {
827
+ return < p > hi forwardRef</ p > ;
828
+ }
829
+ const Test = React . forwardRef ( Test2 ) ;
830
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
831
+ $RefreshReg$ ( Test , 'Test' ) ;
832
+ return Test ;
833
+ } ) ;
834
+ } ) ;
835
+
836
+ // Check remount
837
+ expect ( container . firstChild ) . not . toBe ( el ) ;
838
+ const nextEl = container . firstChild ;
839
+ expect ( nextEl . textContent ) . toBe ( 'hi forwardRef' ) ;
840
+
841
+ // Patch back to a new function
842
+ await act ( async ( ) => {
843
+ await patch ( ( ) => {
844
+ function Test ( ) {
845
+ return < p > hi test1</ p > ;
846
+ }
847
+ $RefreshReg$ ( Test , 'Test' ) ;
848
+ return Test ;
849
+ } ) ;
850
+ } ) ;
851
+
852
+ // Check final remount
853
+ expect ( container . firstChild ) . not . toBe ( nextEl ) ;
854
+ const newEl = container . firstChild ;
855
+ expect ( newEl . textContent ) . toBe ( 'hi test1' ) ;
856
+ }
857
+ } ) ;
858
+
859
+ it ( 'resets state when switching between different component types' , async ( ) => {
860
+ if ( __DEV__ ) {
861
+ await act ( async ( ) => {
862
+ await render ( ( ) => {
863
+ function Test ( ) {
864
+ const [ count , setCount ] = React . useState ( 0 ) ;
865
+ return (
866
+ < div onClick = { ( ) => setCount ( c => c + 1 ) } > count: { count } </ div >
867
+ ) ;
868
+ }
869
+ $RefreshReg$ ( Test , 'Test' ) ;
870
+ return Test ;
871
+ } ) ;
872
+ } ) ;
873
+
874
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 0' ) ;
875
+ await act ( async ( ) => {
876
+ container . firstChild . click ( ) ;
877
+ } ) ;
878
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 1' ) ;
879
+
880
+ await act ( async ( ) => {
881
+ await patch ( ( ) => {
882
+ function Test2 ( ) {
883
+ const [ count , setCount ] = React . useState ( 0 ) ;
884
+ return (
885
+ < div onClick = { ( ) => setCount ( c => c + 1 ) } > count: { count } </ div >
886
+ ) ;
887
+ }
888
+ const Test = React . memo ( Test2 ) ;
889
+ $RefreshReg$ ( Test2 , 'Test2' ) ;
890
+ $RefreshReg$ ( Test , 'Test' ) ;
891
+ return Test ;
892
+ } ) ;
893
+ } ) ;
894
+
895
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 0' ) ;
896
+ await act ( async ( ) => {
897
+ container . firstChild . click ( ) ;
898
+ } ) ;
899
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 1' ) ;
900
+
901
+ await act ( async ( ) => {
902
+ await patch ( ( ) => {
903
+ const Test = React . forwardRef ( ( props , ref ) => {
904
+ const [ count , setCount ] = React . useState ( 0 ) ;
905
+ const handleClick = ( ) => setCount ( c => c + 1 ) ;
906
+
907
+ // Ensure ref is extensible
908
+ const divRef = React . useRef ( null ) ;
909
+ React . useEffect ( ( ) => {
910
+ if ( ref ) {
911
+ if ( typeof ref === 'function' ) {
912
+ ref ( divRef . current ) ;
913
+ } else if ( Object . isExtensible ( ref ) ) {
914
+ ref . current = divRef . current ;
915
+ }
916
+ }
917
+ } , [ ref ] ) ;
918
+
919
+ return (
920
+ < div ref = { divRef } onClick = { handleClick } >
921
+ count: { count }
922
+ </ div >
923
+ ) ;
924
+ } ) ;
925
+ $RefreshReg$ ( Test , 'Test' ) ;
926
+ return Test ;
927
+ } ) ;
928
+ } ) ;
929
+
930
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 0' ) ;
931
+ await act ( async ( ) => {
932
+ container . firstChild . click ( ) ;
933
+ } ) ;
934
+ expect ( container . firstChild . textContent ) . toBe ( 'count: 1' ) ;
935
+ }
936
+ } ) ;
937
+
702
938
it ( 'can update simple memo function in isolation' , async ( ) => {
703
939
if ( __DEV__ ) {
704
940
await render ( ( ) => {
0 commit comments