Add a regression test for switching from Fragment to a component (#17647)
* Add a regression test for switching from Fragment to a component * Add a few more tests
Dan Abramov committed
Dec 18, 2019 at 15:21 UTC
6fef7c47a984cf0d07776c017e58b45f5af8276e
1 file changed
+143
packages/react-reconciler/src/__tests__/ReactFragment-test.js
+143
@@ -722,6 +722,149 @@ describe('ReactFragment', () => {
722
expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
723
});
724
725
+ it('should not preserve state when switching a nested unkeyed fragment to a passthrough component', function() {
726
+ const ops = [];
727
+
728
+ function Passthrough({children}) {
729
+ return children;
730
+ }
731
+
732
+ class Stateful extends React.Component {
733
+ componentDidUpdate() {
734
+ ops.push('Update Stateful');
735
+ }
736
+
737
+ render() {
738
+ return <div>Hello</div>;
739
+ }
740
+ }
741
+
742
+ function Foo({condition}) {
743
+ return condition ? (
744
+ <>
745
+ <>
746
+ <Stateful />
747
+ </>
748
+ </>
749
+ ) : (
750
+ <>
751
+ <Passthrough>
752
+ <Stateful />
753
+ </Passthrough>
754
+ </>
755
+ );
756
+ }
757
+
758
+ ReactNoop.render(<Foo condition={true} />);
759
+ expect(Scheduler).toFlushWithoutYielding();
760
+
761
+ ReactNoop.render(<Foo condition={false} />);
762
+ expect(Scheduler).toFlushWithoutYielding();
763
+
764
+ expect(ops).toEqual([]);
765
+ expect(ReactNoop.getChildren()).toEqual([div()]);
766
+
767
+ ReactNoop.render(<Foo condition={true} />);
768
+ expect(Scheduler).toFlushWithoutYielding();
769
+
770
+ expect(ops).toEqual([]);
771
+ expect(ReactNoop.getChildren()).toEqual([div()]);
772
+ });
773
+
774
+ it('should not preserve state when switching a nested keyed fragment to a passthrough component', function() {
775
+ const ops = [];
776
+
777
+ function Passthrough({children}) {
778
+ return children;
779
+ }
780
+
781
+ class Stateful extends React.Component {
782
+ componentDidUpdate() {
783
+ ops.push('Update Stateful');
784
+ }
785
+
786
+ render() {
787
+ return <div>Hello</div>;
788
+ }
789
+ }
790
+
791
+ function Foo({condition}) {
792
+ return condition ? (
793
+ <>
794
+ <React.Fragment key="a">
795
+ <Stateful />
796
+ </React.Fragment>
797
+ </>
798
+ ) : (
799
+ <>
800
+ <Passthrough>
801
+ <Stateful />
802
+ </Passthrough>
803
+ </>
804
+ );
805
+ }
806
+
807
+ ReactNoop.render(<Foo condition={true} />);
808
+ expect(Scheduler).toFlushWithoutYielding();
809
+
810
+ ReactNoop.render(<Foo condition={false} />);
811
+ expect(Scheduler).toFlushWithoutYielding();
812
+
813
+ expect(ops).toEqual([]);
814
+ expect(ReactNoop.getChildren()).toEqual([div()]);
815
+
816
+ ReactNoop.render(<Foo condition={true} />);
817
+ expect(Scheduler).toFlushWithoutYielding();
818
+
819
+ expect(ops).toEqual([]);
820
+ expect(ReactNoop.getChildren()).toEqual([div()]);
821
+ });
822
+
823
+ it('should not preserve state when switching a nested keyed array to a passthrough component', function() {
824
+ const ops = [];
825
+
826
+ function Passthrough({children}) {
827
+ return children;
828
+ }
829
+
830
+ class Stateful extends React.Component {
831
+ componentDidUpdate() {
832
+ ops.push('Update Stateful');
833
+ }
834
+
835
+ render() {
836
+ return <div>Hello</div>;
837
+ }
838
+ }
839
+
840
+ function Foo({condition}) {
841
+ return condition ? (
842
+ <>{[<Stateful key="a" />]}</>
843
+ ) : (
844
+ <>
845
+ <Passthrough>
846
+ <Stateful />
847
+ </Passthrough>
848
+ </>
849
+ );
850
+ }
851
+
852
+ ReactNoop.render(<Foo condition={true} />);
853
+ expect(Scheduler).toFlushWithoutYielding();
854
+
855
+ ReactNoop.render(<Foo condition={false} />);
856
+ expect(Scheduler).toFlushWithoutYielding();
857
+
858
+ expect(ops).toEqual([]);
859
+ expect(ReactNoop.getChildren()).toEqual([div()]);
860
+
861
+ ReactNoop.render(<Foo condition={true} />);
862
+ expect(Scheduler).toFlushWithoutYielding();
863
+
864
+ expect(ops).toEqual([]);
865
+ expect(ReactNoop.getChildren()).toEqual([div()]);
866
+ });
867
+
868
it('should preserve state when it does not change positions', function() {
869
const ops = [];
870