@samitouri / QOS-React-2 / commits / 05777ffb01

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 });