From 8f3c45b1e3b36ec94b5a16c343dcd1ddaf148cef Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Fri, 24 Feb 2023 22:48:00 -0800 Subject: [PATCH] Setting transition pending flag shouldn't be part of a surrounding transition Fixes #26226. (Is this the right fix?) --- .../react-reconciler/src/ReactFiberHooks.js | 8 ++-- .../src/__tests__/ReactTransition-test.js | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index e9763f9fe289f..ad50043335517 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -2389,11 +2389,11 @@ function startTransition( higherEventPriority(previousPriority, ContinuousEventPriority), ); - setPending(true); - const prevTransition = ReactCurrentBatchConfig.transition; - ReactCurrentBatchConfig.transition = ({}: BatchConfigTransition); - const currentTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = null; + setPending(true); + const currentTransition = (ReactCurrentBatchConfig.transition = + ({}: BatchConfigTransition)); if (enableTransitionTracing) { if (options !== undefined && options.name !== undefined) { diff --git a/packages/react-reconciler/src/__tests__/ReactTransition-test.js b/packages/react-reconciler/src/__tests__/ReactTransition-test.js index 0f63ffe7a1f23..780b70a965b6a 100644 --- a/packages/react-reconciler/src/__tests__/ReactTransition-test.js +++ b/packages/react-reconciler/src/__tests__/ReactTransition-test.js @@ -951,4 +951,43 @@ describe('ReactTransition', () => { expect(root).toMatchRenderedOutput('Transition pri: 1, Normal pri: 1'); }); + + it('tracks two pending flags for nested startTransition (#26226)', async () => { + let update; + function App() { + const [isPendingA, startTransitionA] = useTransition(); + const [isPendingB, startTransitionB] = useTransition(); + const [state, setState] = useState(0); + + update = function () { + startTransitionA(() => { + startTransitionB(() => { + setState(1); + }); + }); + }; + + return ( + <> + + {', '} + + {', '} + + + ); + } + const root = ReactNoop.createRoot(); + await act(async () => { + root.render(); + }); + assertLog([0, 'A false', 'B false']); + expect(root).toMatchRenderedOutput('0, A false, B false'); + + await act(async () => { + update(); + }); + assertLog([0, 'A true', 'B true', 1, 'A false', 'B false']); + expect(root).toMatchRenderedOutput('1, A false, B false'); + }); });