699
'Hooks can only be called inside the body of a function component',
700
);
701
});
702
-
703
- it('double-invokes components with Hooks in Strict Mode', () => {
704
- ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = true;
705
-
706
- const {useState, StrictMode} = React;
707
- let renderCount = 0;
708
-
709
- function NoHooks() {
710
- renderCount++;
711
- return <div />;
712
- }
713
-
714
- function HasHooks() {
715
- useState(0);
716
- renderCount++;
717
- return <div />;
718
- }
719
-
720
- const FwdRef = React.forwardRef((props, ref) => {
721
- renderCount++;
722
- return <div />;
723
- });
724
-
725
- const FwdRefHasHooks = React.forwardRef((props, ref) => {
726
- useState(0);
727
- renderCount++;
728
- return <div />;
729
- });
730
-
731
- const Memo = React.memo(props => {
732
- renderCount++;
733
- return <div />;
734
- });
735
-
736
- const MemoHasHooks = React.memo(props => {
737
- useState(0);
738
- renderCount++;
739
- return <div />;
740
- });
741
-
742
- function Factory() {
743
- return {
744
- state: {},
745
- render() {
746
- renderCount++;
747
- return <div />;
748
- },
749
- };
750
- }
751
-
752
- let renderer = ReactTestRenderer.create(null);
753
-
754
- renderCount = 0;
755
- renderer.update(<NoHooks />);
756
- expect(renderCount).toBe(1);
757
- renderCount = 0;
758
- renderer.update(<NoHooks />);
759
- expect(renderCount).toBe(1);
760
- renderCount = 0;
761
- renderer.update(
762
- <StrictMode>
763
- <NoHooks />
764
- </StrictMode>,
765
- );
766
- expect(renderCount).toBe(1);
767
- renderCount = 0;
768
- renderer.update(
769
- <StrictMode>
770
- <NoHooks />
771
- </StrictMode>,
772
- );
773
- expect(renderCount).toBe(1);
774
-
775
- renderCount = 0;
776
- renderer.update(<FwdRef />);
777
- expect(renderCount).toBe(1);
778
- renderCount = 0;
779
- renderer.update(<FwdRef />);
780
- expect(renderCount).toBe(1);
781
- renderCount = 0;
782
- renderer.update(
783
- <StrictMode>
784
- <FwdRef />
785
- </StrictMode>,
786
- );
787
- expect(renderCount).toBe(1);
788
- renderCount = 0;
789
- renderer.update(
790
- <StrictMode>
791
- <FwdRef />
792
- </StrictMode>,
793
- );
794
- expect(renderCount).toBe(1);
795
-
796
- renderCount = 0;
797
- renderer.update(<Memo arg={1} />);
798
- expect(renderCount).toBe(1);
799
- renderCount = 0;
800
- renderer.update(<Memo arg={2} />);
801
- expect(renderCount).toBe(1);
802
- renderCount = 0;
803
- renderer.update(
804
- <StrictMode>
805
- <Memo arg={1} />
806
- </StrictMode>,
807
- );
808
- expect(renderCount).toBe(1);
809
- renderCount = 0;
810
- renderer.update(
811
- <StrictMode>
812
- <Memo arg={2} />
813
- </StrictMode>,
814
- );
815
- expect(renderCount).toBe(1);
816
-
817
- renderCount = 0;
818
- renderer.update(<Factory />);
819
- expect(renderCount).toBe(1);
820
- renderCount = 0;
821
- renderer.update(<Factory />);
822
- expect(renderCount).toBe(1);
823
- renderCount = 0;
824
- renderer.update(
825
- <StrictMode>
826
- <Factory />
827
- </StrictMode>,
828
- );
829
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Treated like a class
830
- renderCount = 0;
831
- renderer.update(
832
- <StrictMode>
833
- <Factory />
834
- </StrictMode>,
835
- );
836
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Treated like a class
837
-
838
- renderCount = 0;
839
- renderer.update(<HasHooks />);
840
- expect(renderCount).toBe(1);
841
- renderCount = 0;
842
- renderer.update(<HasHooks />);
843
- expect(renderCount).toBe(1);
844
- renderCount = 0;
845
- renderer.update(
846
- <StrictMode>
847
- <HasHooks />
848
- </StrictMode>,
849
- );
850
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
851
- renderCount = 0;
852
- renderer.update(
853
- <StrictMode>
854
- <HasHooks />
855
- </StrictMode>,
856
- );
857
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
858
-
859
- renderCount = 0;
860
- renderer.update(<FwdRefHasHooks />);
861
- expect(renderCount).toBe(1);
862
- renderCount = 0;
863
- renderer.update(<FwdRefHasHooks />);
864
- expect(renderCount).toBe(1);
865
- renderCount = 0;
866
- renderer.update(
867
- <StrictMode>
868
- <FwdRefHasHooks />
869
- </StrictMode>,
870
- );
871
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
872
- renderCount = 0;
873
- renderer.update(
874
- <StrictMode>
875
- <FwdRefHasHooks />
876
- </StrictMode>,
877
- );
878
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
879
-
880
- renderCount = 0;
881
- renderer.update(<MemoHasHooks arg={1} />);
882
- expect(renderCount).toBe(1);
883
- renderCount = 0;
884
- renderer.update(<MemoHasHooks arg={2} />);
885
- expect(renderCount).toBe(1);
886
- renderCount = 0;
887
- renderer.update(
888
- <StrictMode>
889
- <MemoHasHooks arg={1} />
890
- </StrictMode>,
891
- );
892
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
893
- renderCount = 0;
894
- renderer.update(
895
- <StrictMode>
896
- <MemoHasHooks arg={2} />
897
- </StrictMode>,
898
- );
899
- expect(renderCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
900
- });
901
-
902
- it('double-invokes useMemo in DEV StrictMode despite []', () => {
903
- ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = true;
904
- const {useMemo, StrictMode} = React;
905
-
906
- let useMemoCount = 0;
907
- function BadUseMemo() {
908
- useMemo(() => {
909
- useMemoCount++;
910
- }, []);
911
- return <div />;
912
- }
913
-
914
- useMemoCount = 0;
915
- ReactTestRenderer.create(
916
- <StrictMode>
917
- <BadUseMemo />
918
- </StrictMode>,
919
- );
920
- expect(useMemoCount).toBe(__DEV__ ? 2 : 1); // Has Hooks
921
- });
702
});