622
});
623
return <Text text={'Count: ' + props.count} />;
624
}
625
- ReactNoop.render(<Counter count={0} />, () =>
626
- Scheduler.yieldValue('Sync effect'),
627
- );
628
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
629
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
630
- // Effects are deferred until after the commit
631
- expect(Scheduler).toFlushAndYield(['Passive effect [0]']);
625
+ act(() => {
626
+ ReactNoop.render(<Counter count={0} />, () =>
627
+ Scheduler.yieldValue('Sync effect'),
628
+ );
629
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
630
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
631
+ // Effects are deferred until after the commit
632
+ expect(Scheduler).toFlushAndYield(['Passive effect [0]']);
633
+ });
634
633
- ReactNoop.render(<Counter count={1} />, () =>
634
- Scheduler.yieldValue('Sync effect'),
635
- );
636
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
637
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
638
- // Effects are deferred until after the commit
639
- expect(Scheduler).toFlushAndYield(['Passive effect [1]']);
635
+ act(() => {
636
+ ReactNoop.render(<Counter count={1} />, () =>
637
+ Scheduler.yieldValue('Sync effect'),
638
+ );
639
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
640
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
641
+ // Effects are deferred until after the commit
642
+ expect(Scheduler).toFlushAndYield(['Passive effect [1]']);
643
+ });
644
});
645
646
it('flushes passive effects even with sibling deletions', () => {
657
return <Text text="Passive" />;
658
}
659
let passive = <PassiveEffect key="p" />;
656
- ReactNoop.render([<LayoutEffect key="l" />, passive]);
657
- expect(Scheduler).toFlushAndYieldThrough([
658
- 'Layout',
659
- 'Passive',
660
- 'Layout effect',
661
- ]);
662
- expect(ReactNoop.getChildren()).toEqual([
663
- span('Layout'),
664
- span('Passive'),
665
- ]);
666
-
667
- // Destroying the first child shouldn't prevent the passive effect from
668
- // being executed
669
- ReactNoop.render([passive]);
670
- expect(Scheduler).toFlushAndYield(['Passive effect']);
671
- expect(ReactNoop.getChildren()).toEqual([span('Passive')]);
672
-
673
- // (No effects are left to flush.)
674
- ReactNoop.flushPassiveEffects();
660
+ act(() => {
661
+ ReactNoop.render([<LayoutEffect key="l" />, passive]);
662
+ expect(Scheduler).toFlushAndYieldThrough([
663
+ 'Layout',
664
+ 'Passive',
665
+ 'Layout effect',
666
+ ]);
667
+ expect(ReactNoop.getChildren()).toEqual([
668
+ span('Layout'),
669
+ span('Passive'),
670
+ ]);
671
+ // Destroying the first child shouldn't prevent the passive effect from
672
+ // being executed
673
+ ReactNoop.render([passive]);
674
+ expect(Scheduler).toFlushAndYield(['Passive effect']);
675
+ expect(ReactNoop.getChildren()).toEqual([span('Passive')]);
676
+ });
677
+ // exiting act calls flushPassiveEffects(), but there are none left to flush.
678
expect(Scheduler).toHaveYielded([]);
679
});
680
731
});
732
return <Text text="Layout" />;
733
}
731
- ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);
732
- expect(Scheduler).toFlushAndYield([
733
- 'Passive',
734
- 'Layout',
735
- 'Layout effect',
736
- 'Passive effect',
737
- 'New Root',
738
- ]);
739
- expect(ReactNoop.getChildren()).toEqual([
740
- span('Passive'),
741
- span('Layout'),
742
- ]);
734
+ act(() => {
735
+ ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);
736
+ expect(Scheduler).toFlushAndYield([
737
+ 'Passive',
738
+ 'Layout',
739
+ 'Layout effect',
740
+ 'Passive effect',
741
+ 'New Root',
742
+ ]);
743
+ expect(ReactNoop.getChildren()).toEqual([
744
+ span('Passive'),
745
+ span('Layout'),
746
+ ]);
747
+ });
748
});
749
750
it(
767
});
768
return <Text text={props.count} />;
769
}
765
- ReactNoop.render(<Counter count={0} />, () =>
766
- Scheduler.yieldValue('Sync effect'),
767
- );
768
- expect(Scheduler).toFlushAndYieldThrough([0, 'Sync effect']);
769
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
770
-
771
- // Before the effects have a chance to flush, schedule another update
772
- ReactNoop.render(<Counter count={1} />, () =>
773
- Scheduler.yieldValue('Sync effect'),
774
- );
775
- expect(Scheduler).toFlushAndYieldThrough([
776
- // The previous effect flushes before the reconciliation
777
- 'Committed state when effect was fired: 0',
778
- 1,
779
- 'Sync effect',
780
- ]);
781
- expect(ReactNoop.getChildren()).toEqual([span(1)]);
770
+ act(() => {
771
+ ReactNoop.render(<Counter count={0} />, () =>
772
+ Scheduler.yieldValue('Sync effect'),
773
+ );
774
+ expect(Scheduler).toFlushAndYieldThrough([0, 'Sync effect']);
775
+ expect(ReactNoop.getChildren()).toEqual([span(0)]);
776
+ // Before the effects have a chance to flush, schedule another update
777
+ ReactNoop.render(<Counter count={1} />, () =>
778
+ Scheduler.yieldValue('Sync effect'),
779
+ );
780
+ expect(Scheduler).toFlushAndYieldThrough([
781
+ // The previous effect flushes before the reconciliation
782
+ 'Committed state when effect was fired: 0',
783
+ 1,
784
+ 'Sync effect',
785
+ ]);
786
+ expect(ReactNoop.getChildren()).toEqual([span(1)]);
787
+ });
788
783
- ReactNoop.flushPassiveEffects();
789
expect(Scheduler).toHaveYielded([
790
'Committed state when effect was fired: 1',
791
]);
804
);
805
return <Text text={'Count: ' + count} />;
806
}
802
- ReactNoop.render(<Counter count={0} />, () =>
803
- Scheduler.yieldValue('Sync effect'),
804
- );
805
- expect(Scheduler).toFlushAndYieldThrough([
806
- 'Count: (empty)',
807
- 'Sync effect',
808
- ]);
809
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
810
- ReactNoop.flushPassiveEffects();
811
- expect(Scheduler).toHaveYielded(['Schedule update [0]']);
812
- expect(Scheduler).toFlushAndYield(['Count: 0']);
807
+ act(() => {
808
+ ReactNoop.render(<Counter count={0} />, () =>
809
+ Scheduler.yieldValue('Sync effect'),
810
+ );
811
+ expect(Scheduler).toFlushAndYieldThrough([
812
+ 'Count: (empty)',
813
+ 'Sync effect',
814
+ ]);
815
+ expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
816
+ ReactNoop.flushPassiveEffects();
817
+ expect(Scheduler).toHaveYielded(['Schedule update [0]']);
818
+ expect(Scheduler).toFlushAndYield(['Count: 0']);
819
+ });
820
814
- ReactNoop.render(<Counter count={1} />, () =>
815
- Scheduler.yieldValue('Sync effect'),
816
- );
817
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
818
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
819
- ReactNoop.flushPassiveEffects();
820
- expect(Scheduler).toHaveYielded(['Schedule update [1]']);
821
- expect(Scheduler).toFlushAndYield(['Count: 1']);
821
+ act(() => {
822
+ ReactNoop.render(<Counter count={1} />, () =>
823
+ Scheduler.yieldValue('Sync effect'),
824
+ );
825
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
826
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
827
+ ReactNoop.flushPassiveEffects();
828
+ expect(Scheduler).toHaveYielded(['Schedule update [1]']);
829
+ expect(Scheduler).toFlushAndYield(['Count: 1']);
830
+ });
831
});
832
833
it('updates have async priority even if effects are flushed early', () => {
842
);
843
return <Text text={'Count: ' + count} />;
844
}
836
- ReactNoop.render(<Counter count={0} />, () =>
837
- Scheduler.yieldValue('Sync effect'),
838
- );
839
- expect(Scheduler).toFlushAndYieldThrough([
840
- 'Count: (empty)',
841
- 'Sync effect',
842
- ]);
843
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
844
-
845
- // Rendering again should flush the previous commit's effects
846
- ReactNoop.render(<Counter count={1} />, () =>
847
- Scheduler.yieldValue('Sync effect'),
848
- );
849
- expect(Scheduler).toFlushAndYieldThrough([
850
- 'Schedule update [0]',
851
- 'Count: 0',
852
- ]);
853
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
845
+ act(() => {
846
+ ReactNoop.render(<Counter count={0} />, () =>
847
+ Scheduler.yieldValue('Sync effect'),
848
+ );
849
+ expect(Scheduler).toFlushAndYieldThrough([
850
+ 'Count: (empty)',
851
+ 'Sync effect',
852
+ ]);
853
+ expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
854
855
- expect(Scheduler).toFlushAndYieldThrough(['Sync effect']);
856
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
855
+ // Rendering again should flush the previous commit's effects
856
+ ReactNoop.render(<Counter count={1} />, () =>
857
+ Scheduler.yieldValue('Sync effect'),
858
+ );
859
+ expect(Scheduler).toFlushAndYieldThrough([
860
+ 'Schedule update [0]',
861
+ 'Count: 0',
862
+ ]);
863
+ expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
864
858
- ReactNoop.flushPassiveEffects();
859
- expect(Scheduler).toHaveYielded(['Schedule update [1]']);
860
- expect(Scheduler).toFlushAndYield(['Count: 1']);
861
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
865
+ expect(Scheduler).toFlushAndYieldThrough(['Sync effect']);
866
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
867
+ ReactNoop.flushPassiveEffects();
868
+ expect(Scheduler).toHaveYielded(['Schedule update [1]']);
869
+ expect(Scheduler).toFlushAndYield(['Count: 1']);
870
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
871
+ });
872
});
873
874
it('flushes passive effects when flushing discrete updates', () => {
883
return <Text text={'Count: ' + count} />;
884
}
885
876
- ReactNoop.render(<Counter count={0} />, () =>
877
- Scheduler.yieldValue('Sync effect'),
878
- );
879
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
880
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
886
+ // we explicitly wait for missing act() warnings here since
887
+ // it's a lot harder to simulate this condition inside an act scope
888
+ expect(() => {
889
+ ReactNoop.render(<Counter count={0} />, () =>
890
+ Scheduler.yieldValue('Sync effect'),
891
+ );
892
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
893
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
894
+ }).toWarnDev(['An update to Counter ran an effect']);
895
896
// A discrete event forces the passive effect to be flushed --
897
// updateCount(1) happens first, so 2 wins.
884
-
898
ReactNoop.flushDiscreteUpdates();
899
ReactNoop.discreteUpdates(() => {
900
// (use batchedUpdates to silence the act() warning)
903
});
904
});
905
expect(Scheduler).toHaveYielded(['Will set count to 1']);
893
- expect(Scheduler).toFlushAndYield(['Count: 2']);
906
+ expect(() => {
907
+ expect(Scheduler).toFlushAndYield(['Count: 2']);
908
+ }).toWarnDev([
909
+ 'An update to Counter ran an effect',
910
+ 'An update to Counter ran an effect',
911
+ ]);
912
+
913
expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
914
});
915
940
}
941
942
const tracingEvent = {id: 0, name: 'hello', timestamp: 0};
924
- SchedulerTracing.unstable_trace(
925
- tracingEvent.name,
926
- tracingEvent.timestamp,
927
- () => {
928
- ReactNoop.render(<Counter count={0} />, () =>
929
- Scheduler.yieldValue('Sync effect'),
930
- );
931
- },
932
- );
933
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
934
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
943
+ // we explicitly wait for missing act() warnings here since
944
+ // it's a lot harder to simulate this condition inside an act scope
945
+ expect(() => {
946
+ SchedulerTracing.unstable_trace(
947
+ tracingEvent.name,
948
+ tracingEvent.timestamp,
949
+ () => {
950
+ ReactNoop.render(<Counter count={0} />, () =>
951
+ Scheduler.yieldValue('Sync effect'),
952
+ );
953
+ },
954
+ );
955
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
956
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
957
+ }).toWarnDev(['An update to Counter ran an effect']);
958
959
expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(0);
960
962
// updateCount(1) happens first, so 2 wins.
963
ReactNoop.flushDiscreteUpdates();
964
ReactNoop.discreteUpdates(() => {
942
- // use batchedUpdates to silence the act warning
943
- ReactNoop.batchedUpdates(() => _updateCount(2));
965
+ // (use batchedUpdates to silence the act() warning)
966
+ ReactNoop.batchedUpdates(() => {
967
+ _updateCount(2);
968
+ });
969
});
970
expect(Scheduler).toHaveYielded(['Will set count to 1']);
946
- expect(Scheduler).toFlushAndYield(['Count: 2']);
971
+ expect(() => {
972
+ expect(Scheduler).toFlushAndYield(['Count: 2']);
973
+ }).toWarnDev([
974
+ 'An update to Counter ran an effect',
975
+ 'An update to Counter ran an effect',
976
+ ]);
977
+
978
expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
979
980
expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);
1002
);
1003
return <Text text={'Count: ' + count} />;
1004
}
974
- ReactNoop.renderLegacySyncRoot(<Counter count={0} />);
975
- // Even in sync mode, effects are deferred until after paint
976
- expect(Scheduler).toHaveYielded(['Count: (empty)']);
977
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
978
- // Now fire the effects
979
- ReactNoop.flushPassiveEffects();
1005
+ act(() => {
1006
+ ReactNoop.renderLegacySyncRoot(<Counter count={0} />);
1007
+ // Even in sync mode, effects are deferred until after paint
1008
+ expect(Scheduler).toFlushAndYieldThrough(['Count: (empty)']);
1009
+ expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
1010
+ });
1011
+
1012
+ // effects get fored on exiting act()
1013
// There were multiple updates, but there should only be a
1014
// single render
1015
expect(Scheduler).toHaveYielded(['Count: 0']);
1031
);
1032
return <Text text={'Count: ' + count} />;
1033
}
1001
- ReactNoop.render(<Counter count={0} />, () =>
1002
- Scheduler.yieldValue('Sync effect'),
1003
- );
1004
- expect(Scheduler).toFlushAndYieldThrough([
1005
- 'Count: (empty)',
1006
- 'Sync effect',
1007
- ]);
1008
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
1009
-
1010
- expect(() => {
1011
- ReactNoop.flushPassiveEffects();
1012
- }).toThrow('flushSync was called from inside a lifecycle method');
1034
+ act(() => {
1035
+ ReactNoop.render(<Counter count={0} />, () =>
1036
+ Scheduler.yieldValue('Sync effect'),
1037
+ );
1038
+ expect(Scheduler).toFlushAndYieldThrough([
1039
+ 'Count: (empty)',
1040
+ 'Sync effect',
1041
+ ]);
1042
+ expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
1043
+ expect(() => {
1044
+ ReactNoop.flushPassiveEffects();
1045
+ }).toThrow('flushSync was called from inside a lifecycle method');
1046
+ });
1047
});
1048
1049
it('unmounts previous effect', () => {
1056
});
1057
return <Text text={'Count: ' + props.count} />;
1058
}
1025
- ReactNoop.render(<Counter count={0} />, () =>
1026
- Scheduler.yieldValue('Sync effect'),
1027
- );
1028
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1029
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1030
- ReactNoop.flushPassiveEffects();
1059
+ act(() => {
1060
+ ReactNoop.render(<Counter count={0} />, () =>
1061
+ Scheduler.yieldValue('Sync effect'),
1062
+ );
1063
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1064
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1065
+ });
1066
+
1067
expect(Scheduler).toHaveYielded(['Did create [0]']);
1068
1033
- ReactNoop.render(<Counter count={1} />, () =>
1034
- Scheduler.yieldValue('Sync effect'),
1035
- );
1036
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1037
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1038
- ReactNoop.flushPassiveEffects();
1069
+ act(() => {
1070
+ ReactNoop.render(<Counter count={1} />, () =>
1071
+ Scheduler.yieldValue('Sync effect'),
1072
+ );
1073
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1074
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1075
+ });
1076
+
1077
expect(Scheduler).toHaveYielded(['Did destroy [0]', 'Did create [1]']);
1078
});
1079
1087
});
1088
return <Text text={'Count: ' + props.count} />;
1089
}
1052
- ReactNoop.render(<Counter count={0} />, () =>
1053
- Scheduler.yieldValue('Sync effect'),
1054
- );
1055
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1056
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1057
- ReactNoop.flushPassiveEffects();
1090
+ act(() => {
1091
+ ReactNoop.render(<Counter count={0} />, () =>
1092
+ Scheduler.yieldValue('Sync effect'),
1093
+ );
1094
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1095
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1096
+ });
1097
+
1098
expect(Scheduler).toHaveYielded(['Did create [0]']);
1099
1100
ReactNoop.render(null);
1112
}, []);
1113
return <Text text={'Count: ' + props.count} />;
1114
}
1075
- ReactNoop.render(<Counter count={0} />, () =>
1076
- Scheduler.yieldValue('Sync effect'),
1077
- );
1078
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1079
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1080
- ReactNoop.flushPassiveEffects();
1115
+ act(() => {
1116
+ ReactNoop.render(<Counter count={0} />, () =>
1117
+ Scheduler.yieldValue('Sync effect'),
1118
+ );
1119
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1120
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1121
+ });
1122
+
1123
expect(Scheduler).toHaveYielded(['Did create [0]']);
1124
1083
- ReactNoop.render(<Counter count={1} />, () =>
1084
- Scheduler.yieldValue('Sync effect'),
1085
- );
1086
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1087
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1088
- ReactNoop.flushPassiveEffects();
1125
+ act(() => {
1126
+ ReactNoop.render(<Counter count={1} />, () =>
1127
+ Scheduler.yieldValue('Sync effect'),
1128
+ );
1129
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1130
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1131
+ });
1132
+
1133
expect(Scheduler).toHaveYielded([]);
1134
1135
ReactNoop.render(null);
1148
useEffect(effect);
1149
return <Text text={'Count: ' + props.count} />;
1150
}
1107
- ReactNoop.render(<Counter count={0} />, () =>
1108
- Scheduler.yieldValue('Sync effect'),
1109
- );
1110
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1111
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1112
- ReactNoop.flushPassiveEffects();
1151
+ act(() => {
1152
+ ReactNoop.render(<Counter count={0} />, () =>
1153
+ Scheduler.yieldValue('Sync effect'),
1154
+ );
1155
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1156
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1157
+ });
1158
+
1159
expect(Scheduler).toHaveYielded(['Did create']);
1160
1115
- ReactNoop.render(<Counter count={1} />, () =>
1116
- Scheduler.yieldValue('Sync effect'),
1117
- );
1118
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1119
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1120
- ReactNoop.flushPassiveEffects();
1161
+ act(() => {
1162
+ ReactNoop.render(<Counter count={1} />, () =>
1163
+ Scheduler.yieldValue('Sync effect'),
1164
+ );
1165
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1166
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1167
+ });
1168
+
1169
expect(Scheduler).toHaveYielded(['Did destroy', 'Did create']);
1170
1171
ReactNoop.render(null);
1187
);
1188
return <Text text={text} />;
1189
}
1142
- ReactNoop.render(<Counter label="Count" count={0} />, () =>
1143
- Scheduler.yieldValue('Sync effect'),
1144
- );
1145
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1146
- ReactNoop.flushPassiveEffects();
1190
+ act(() => {
1191
+ ReactNoop.render(<Counter label="Count" count={0} />, () =>
1192
+ Scheduler.yieldValue('Sync effect'),
1193
+ );
1194
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1195
+ });
1196
+
1197
expect(Scheduler).toHaveYielded(['Did create [Count: 0]']);
1198
expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1199
1150
- ReactNoop.render(<Counter label="Count" count={1} />, () =>
1151
- Scheduler.yieldValue('Sync effect'),
1152
- );
1153
- // Count changed
1154
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1155
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1156
- ReactNoop.flushPassiveEffects();
1200
+ act(() => {
1201
+ ReactNoop.render(<Counter label="Count" count={1} />, () =>
1202
+ Scheduler.yieldValue('Sync effect'),
1203
+ );
1204
+ // Count changed
1205
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1206
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1207
+ });
1208
+
1209
expect(Scheduler).toHaveYielded([
1210
'Did destroy [Count: 0]',
1211
'Did create [Count: 1]',
1212
]);
1213
1162
- ReactNoop.render(<Counter label="Count" count={1} />, () =>
1163
- Scheduler.yieldValue('Sync effect'),
1164
- );
1165
- // Nothing changed, so no effect should have fired
1166
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1167
- ReactNoop.flushPassiveEffects();
1214
+ act(() => {
1215
+ ReactNoop.render(<Counter label="Count" count={1} />, () =>
1216
+ Scheduler.yieldValue('Sync effect'),
1217
+ );
1218
+ // Nothing changed, so no effect should have fired
1219
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1220
+ });
1221
+
1222
expect(Scheduler).toHaveYielded([]);
1223
expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1224
1171
- ReactNoop.render(<Counter label="Total" count={1} />, () =>
1172
- Scheduler.yieldValue('Sync effect'),
1173
- );
1174
- // Label changed
1175
- expect(Scheduler).toFlushAndYieldThrough(['Total: 1', 'Sync effect']);
1176
- expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);
1177
- ReactNoop.flushPassiveEffects();
1225
+ act(() => {
1226
+ ReactNoop.render(<Counter label="Total" count={1} />, () =>
1227
+ Scheduler.yieldValue('Sync effect'),
1228
+ );
1229
+ // Label changed
1230
+ expect(Scheduler).toFlushAndYieldThrough(['Total: 1', 'Sync effect']);
1231
+ expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);
1232
+ });
1233
+
1234
expect(Scheduler).toHaveYielded([
1235
'Did destroy [Count: 1]',
1236
'Did create [Total: 1]',
1247
});
1248
return <Text text={'Count: ' + props.count} />;
1249
}
1194
- ReactNoop.render(<Counter count={0} />, () =>
1195
- Scheduler.yieldValue('Sync effect'),
1196
- );
1197
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1198
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1199
- ReactNoop.flushPassiveEffects();
1250
+ act(() => {
1251
+ ReactNoop.render(<Counter count={0} />, () =>
1252
+ Scheduler.yieldValue('Sync effect'),
1253
+ );
1254
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1255
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1256
+ });
1257
+
1258
expect(Scheduler).toHaveYielded(['Did commit 1 [0]', 'Did commit 2 [0]']);
1259
1202
- ReactNoop.render(<Counter count={1} />, () =>
1203
- Scheduler.yieldValue('Sync effect'),
1204
- );
1205
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1206
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1207
- ReactNoop.flushPassiveEffects();
1260
+ act(() => {
1261
+ ReactNoop.render(<Counter count={1} />, () =>
1262
+ Scheduler.yieldValue('Sync effect'),
1263
+ );
1264
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1265
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1266
+ });
1267
expect(Scheduler).toHaveYielded(['Did commit 1 [1]', 'Did commit 2 [1]']);
1268
});
1269
1283
});
1284
return <Text text={'Count: ' + props.count} />;
1285
}
1227
- ReactNoop.render(<Counter count={0} />, () =>
1228
- Scheduler.yieldValue('Sync effect'),
1229
- );
1230
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1231
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1232
- ReactNoop.flushPassiveEffects();
1286
+ act(() => {
1287
+ ReactNoop.render(<Counter count={0} />, () =>
1288
+ Scheduler.yieldValue('Sync effect'),
1289
+ );
1290
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1291
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1292
+ });
1293
+
1294
expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1295
1235
- ReactNoop.render(<Counter count={1} />, () =>
1236
- Scheduler.yieldValue('Sync effect'),
1237
- );
1238
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1239
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1240
- ReactNoop.flushPassiveEffects();
1296
+ act(() => {
1297
+ ReactNoop.render(<Counter count={1} />, () =>
1298
+ Scheduler.yieldValue('Sync effect'),
1299
+ );
1300
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1301
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1302
+ });
1303
expect(Scheduler).toHaveYielded([
1304
'Unmount A [0]',
1305
'Unmount B [0]',
1327
});
1328
return <Text text={'Count: ' + props.count} />;
1329
}
1268
- ReactNoop.render(<Counter count={0} />, () =>
1269
- Scheduler.yieldValue('Sync effect'),
1270
- );
1271
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1272
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1273
- expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1330
+ act(() => {
1331
+ ReactNoop.render(<Counter count={0} />, () =>
1332
+ Scheduler.yieldValue('Sync effect'),
1333
+ );
1334
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1335
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1336
+ expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1337
+ });
1338
+
1339
expect(Scheduler).toHaveYielded([
1340
'Mount A [0]',
1341
'Oops!',
1366
});
1367
return <Text text={'Count: ' + props.count} />;
1368
}
1304
- ReactNoop.render(<Counter count={0} />, () =>
1305
- Scheduler.yieldValue('Sync effect'),
1306
- );
1307
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1308
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1309
- ReactNoop.flushPassiveEffects();
1310
- expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1369
+ act(() => {
1370
+ ReactNoop.render(<Counter count={0} />, () =>
1371
+ Scheduler.yieldValue('Sync effect'),
1372
+ );
1373
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1374
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1375
+ ReactNoop.flushPassiveEffects();
1376
+ expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1377
+ });
1378
1312
- // This update will trigger an errror
1313
- ReactNoop.render(<Counter count={1} />, () =>
1314
- Scheduler.yieldValue('Sync effect'),
1315
- );
1316
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1317
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1318
- expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1319
- expect(Scheduler).toHaveYielded([
1320
- 'Unmount A [0]',
1321
- 'Unmount B [0]',
1322
- 'Mount A [1]',
1323
- 'Oops!',
1324
- // Clean up effect A. There's no effect B to clean-up, because it
1325
- // never mounted.
1326
- 'Unmount A [1]',
1327
- ]);
1328
- expect(ReactNoop.getChildren()).toEqual([]);
1379
+ act(() => {
1380
+ // This update will trigger an errror
1381
+ ReactNoop.render(<Counter count={1} />, () =>
1382
+ Scheduler.yieldValue('Sync effect'),
1383
+ );
1384
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1385
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1386
+ expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1387
+ expect(Scheduler).toHaveYielded([
1388
+ 'Unmount A [0]',
1389
+ 'Unmount B [0]',
1390
+ 'Mount A [1]',
1391
+ 'Oops!',
1392
+ // Clean up effect A. There's no effect B to clean-up, because it
1393
+ // never mounted.
1394
+ 'Unmount A [1]',
1395
+ ]);
1396
+ expect(ReactNoop.getChildren()).toEqual([]);
1397
+ });
1398
});
1399
1400
it('handles errors on unmount', () => {
1416
});
1417
return <Text text={'Count: ' + props.count} />;
1418
}
1350
- ReactNoop.render(<Counter count={0} />, () =>
1351
- Scheduler.yieldValue('Sync effect'),
1352
- );
1353
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1354
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1355
- ReactNoop.flushPassiveEffects();
1356
- expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1419
+ act(() => {
1420
+ ReactNoop.render(<Counter count={0} />, () =>
1421
+ Scheduler.yieldValue('Sync effect'),
1422
+ );
1423
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
1424
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1425
+ ReactNoop.flushPassiveEffects();
1426
+ expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1427
+ });
1428
1358
- // This update will trigger an errror
1359
- ReactNoop.render(<Counter count={1} />, () =>
1360
- Scheduler.yieldValue('Sync effect'),
1361
- );
1362
- expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1363
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1364
- expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1365
- expect(Scheduler).toHaveYielded([
1366
- 'Oops!',
1367
- // B unmounts even though an error was thrown in the previous effect
1368
- 'Unmount B [0]',
1369
- ]);
1370
- expect(ReactNoop.getChildren()).toEqual([]);
1429
+ act(() => {
1430
+ // This update will trigger an errror
1431
+ ReactNoop.render(<Counter count={1} />, () =>
1432
+ Scheduler.yieldValue('Sync effect'),
1433
+ );
1434
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
1435
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1436
+ expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1437
+ expect(Scheduler).toHaveYielded([
1438
+ 'Oops!',
1439
+ // B unmounts even though an error was thrown in the previous effect
1440
+ 'Unmount B [0]',
1441
+ ]);
1442
+ expect(ReactNoop.getChildren()).toEqual([]);
1443
+ });
1444
});
1445
1446
it('works with memo', () => {
1543
return null;
1544
}
1545
1473
- ReactNoop.render(<Counter count={0} />, () =>
1474
- Scheduler.yieldValue('Sync effect'),
1475
- );
1476
- expect(Scheduler).toFlushAndYieldThrough([
1477
- 'Mount layout [current: 0]',
1478
- 'Sync effect',
1479
- ]);
1480
- expect(committedText).toEqual('0');
1481
-
1482
- ReactNoop.render(<Counter count={1} />, () =>
1483
- Scheduler.yieldValue('Sync effect'),
1484
- );
1485
- expect(Scheduler).toFlushAndYieldThrough([
1486
- 'Mount normal [current: 0]',
1487
- 'Unmount layout [current: 0]',
1488
- 'Mount layout [current: 1]',
1489
- 'Sync effect',
1490
- ]);
1491
- expect(committedText).toEqual('1');
1546
+ act(() => {
1547
+ ReactNoop.render(<Counter count={0} />, () =>
1548
+ Scheduler.yieldValue('Sync effect'),
1549
+ );
1550
+ expect(Scheduler).toFlushAndYieldThrough([
1551
+ 'Mount layout [current: 0]',
1552
+ 'Sync effect',
1553
+ ]);
1554
+ expect(committedText).toEqual('0');
1555
+ ReactNoop.render(<Counter count={1} />, () =>
1556
+ Scheduler.yieldValue('Sync effect'),
1557
+ );
1558
+ expect(Scheduler).toFlushAndYieldThrough([
1559
+ 'Mount normal [current: 0]',
1560
+ 'Unmount layout [current: 0]',
1561
+ 'Mount layout [current: 1]',
1562
+ 'Sync effect',
1563
+ ]);
1564
+ expect(committedText).toEqual('1');
1565
+ });
1566
1493
- ReactNoop.flushPassiveEffects();
1567
expect(Scheduler).toHaveYielded([
1568
'Unmount normal [current: 1]',
1569
'Mount normal [current: 1]',
1757
return null;
1758
}
1759
1687
- ReactNoop.render(<App />);
1688
- expect(Scheduler).toFlushAndYield([]);
1760
+ act(() => {
1761
+ ReactNoop.render(<App />);
1762
+ });
1763
+ expect(Scheduler).toHaveYielded([]);
1764
1765
ping(1);
1766
ping(2);
2038
return null;
2039
}
2040
1966
- ReactNoop.render(<App showMore={false} />, () =>
1967
- Scheduler.yieldValue('Sync effect'),
1968
- );
1969
- expect(Scheduler).toFlushAndYieldThrough(['Sync effect']);
1970
- ReactNoop.flushPassiveEffects();
2041
+ act(() => {
2042
+ ReactNoop.render(<App showMore={false} />, () =>
2043
+ Scheduler.yieldValue('Sync effect'),
2044
+ );
2045
+ expect(Scheduler).toFlushAndYieldThrough(['Sync effect']);
2046
+ });
2047
+
2048
expect(Scheduler).toHaveYielded(['Mount A']);
2049
1973
- ReactNoop.render(<App showMore={true} />);
1974
- expect(() => {
2050
+ act(() => {
2051
+ ReactNoop.render(<App showMore={true} />);
2052
expect(() => {
1976
- expect(Scheduler).toFlushAndYield([]);
1977
- }).toThrow('Rendered more hooks than during the previous render');
1978
- }).toWarnDev([
1979
- 'Warning: React has detected a change in the order of Hooks called by App. ' +
1980
- 'This will lead to bugs and errors if not fixed. For more information, ' +
1981
- 'read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' +
1982
- ' Previous render Next render\n' +
1983
- ' ------------------------------------------------------\n' +
1984
- '1. useEffect useEffect\n' +
1985
- '2. undefined useEffect\n' +
1986
- ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n',
1987
- ]);
2053
+ expect(() => {
2054
+ expect(Scheduler).toFlushAndYield([]);
2055
+ }).toThrow('Rendered more hooks than during the previous render');
2056
+ }).toWarnDev([
2057
+ 'Warning: React has detected a change in the order of Hooks called by App. ' +
2058
+ 'This will lead to bugs and errors if not fixed. For more information, ' +
2059
+ 'read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' +
2060
+ ' Previous render Next render\n' +
2061
+ ' ------------------------------------------------------\n' +
2062
+ '1. useEffect useEffect\n' +
2063
+ '2. undefined useEffect\n' +
2064
+ ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n',
2065
+ ]);
2066
+ });
2067
2068
// Uncomment if/when we support this again
2069
// ReactNoop.flushPassiveEffects();
2105
return count;
2106
}
2107
2029
- ReactNoop.render(<App />);
2030
- expect(Scheduler).toFlushAndYield([
2031
- 'Render: -1',
2032
- 'Effect: 1',
2033
- 'Reducer: 1',
2034
- 'Reducer: 1',
2035
- 'Render: 1',
2036
- ]);
2037
- expect(ReactNoop).toMatchRenderedOutput('1');
2108
+ act(() => {
2109
+ ReactNoop.render(<App />);
2110
+ expect(Scheduler).toFlushAndYield([
2111
+ 'Render: -1',
2112
+ 'Effect: 1',
2113
+ 'Reducer: 1',
2114
+ 'Reducer: 1',
2115
+ 'Render: 1',
2116
+ ]);
2117
+ expect(ReactNoop).toMatchRenderedOutput('1');
2118
+ });
2119
2120
act(() => {
2121
setCounter(2);
2190
return <Text text={'Count: ' + count} />;
2191
}
2192
2112
- ReactNoop.render(<Counter count={0} />, () =>
2113
- Scheduler.yieldValue('Sync effect'),
2114
- );
2115
- expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
2116
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
2117
-
2118
- // Enqueuing this update forces the passive effect to be flushed --
2119
- // updateCount(1) happens first, so 2 wins.
2120
- // (use batchedUpdates to silence the act() warning)
2121
- ReactNoop.batchedUpdates(() => _updateCount(2));
2122
- expect(Scheduler).toHaveYielded(['Will set count to 1']);
2123
- expect(Scheduler).toFlushAndYield(['Count: 2']);
2124
- expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
2193
+ act(() => {
2194
+ ReactNoop.render(<Counter count={0} />, () =>
2195
+ Scheduler.yieldValue('Sync effect'),
2196
+ );
2197
+ expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
2198
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
2199
+ // Enqueuing this update forces the passive effect to be flushed --
2200
+ // updateCount(1) happens first, so 2 wins.
2201
+ act(() => _updateCount(2));
2202
+ expect(Scheduler).toHaveYielded(['Will set count to 1']);
2203
+ expect(Scheduler).toFlushAndYield(['Count: 2']);
2204
+ expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
2205
+ });
2206
});
2207
});
2208
});