Setting transition pending flag shouldn't be part of a surrounding transition (#26243)
Fixes #26226. (Is this the right fix?)
Sophie Alpert committed
Mar 15, 2023 at 18:10 UTC
05777ffb01515679d73541062a4ecc745af04a2f
2 files changed
+43
-4
packages/react-reconciler/src/ReactFiberHooks.js
+4
-4
@@ -2389,11 +2389,11 @@ function startTransition(
2389
higherEventPriority(previousPriority, ContinuousEventPriority),
2390
);
2391
2392
- setPending(true);
2393
-
2392
const prevTransition = ReactCurrentBatchConfig.transition;
2395
- ReactCurrentBatchConfig.transition = ({}: BatchConfigTransition);
2396
- const currentTransition = ReactCurrentBatchConfig.transition;
2393
+ ReactCurrentBatchConfig.transition = null;
2394
+ setPending(true);
2395
+ const currentTransition = (ReactCurrentBatchConfig.transition =
2396
+ ({}: BatchConfigTransition));
2397
2398
if (enableTransitionTracing) {
2399
if (options !== undefined && options.name !== undefined) {
packages/react-reconciler/src/__tests__/ReactTransition-test.js
+39
@@ -951,4 +951,43 @@ describe('ReactTransition', () => {
951
952
expect(root).toMatchRenderedOutput('Transition pri: 1, Normal pri: 1');
953
});
954
+
955
+ it('tracks two pending flags for nested startTransition (#26226)', async () => {
956
+ let update;
957
+ function App() {
958
+ const [isPendingA, startTransitionA] = useTransition();
959
+ const [isPendingB, startTransitionB] = useTransition();
960
+ const [state, setState] = useState(0);
961
+
962
+ update = function () {
963
+ startTransitionA(() => {
964
+ startTransitionB(() => {
965
+ setState(1);
966
+ });
967
+ });
968
+ };
969
+
970
+ return (
971
+ <>
972
+ <Text text={state} />
973
+ {', '}
974
+ <Text text={'A ' + isPendingA} />
975
+ {', '}
976
+ <Text text={'B ' + isPendingB} />
977
+ </>
978
+ );
979
+ }
980
+ const root = ReactNoop.createRoot();
981
+ await act(async () => {
982
+ root.render(<App />);
983
+ });
984
+ assertLog([0, 'A false', 'B false']);
985
+ expect(root).toMatchRenderedOutput('0, A false, B false');
986
+
987
+ await act(async () => {
988
+ update();
989
+ });
990
+ assertLog([0, 'A true', 'B true', 1, 'A false', 'B false']);
991
+ expect(root).toMatchRenderedOutput('1, A false, B false');
992
+ });
993
});