Skip to content

Commit 0cac32d

Browse files
authored
[Fiber] Stash the entangled async action lane on currentEventTransitionLane (facebook#33188)
When we're entangled with an async action lane we use that lane instead of the currentEventTransitionLane. Conversely, if we start a new async action lane we reuse the currentEventTransitionLane. So they're basically supposed to be in sync but they're not if you resolve the async action and then schedule new stuff in the same event. Then you end up with two transitions in the same event with different lanes. By stashing it like this we fix that but it also gives us an opportunity to check just the currentEventTransitionLane to see if this event scheduled any regular Transition updates or Async Transitions.
1 parent 676f087 commit 0cac32d

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

packages/react-reconciler/src/ReactFiberRootScheduler.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import {
7878
resetNestedUpdateFlag,
7979
syncNestedUpdateFlag,
8080
} from './ReactProfilerTimer';
81+
import {peekEntangledActionLane} from './ReactFiberAsyncAction';
8182

8283
// A linked list of all the roots with pending work. In an idiomatic app,
8384
// there's only a single root, but we do support multi root apps, hence this
@@ -647,7 +648,15 @@ export function requestTransitionLane(
647648
// over. Our heuristic for that is whenever we enter a concurrent work loop.
648649
if (currentEventTransitionLane === NoLane) {
649650
// All transitions within the same event are assigned the same lane.
650-
currentEventTransitionLane = claimNextTransitionLane();
651+
const actionScopeLane = peekEntangledActionLane();
652+
currentEventTransitionLane =
653+
actionScopeLane !== NoLane
654+
? // We're inside an async action scope. Reuse the same lane.
655+
actionScopeLane
656+
: // We may or may not be inside an async action scope. If we are, this
657+
// is the first update in that scope. Either way, we need to get a
658+
// fresh transition lane.
659+
claimNextTransitionLane();
651660
}
652661
return currentEventTransitionLane;
653662
}

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ import {
356356
requestTransitionLane,
357357
} from './ReactFiberRootScheduler';
358358
import {getMaskedContext, getUnmaskedContext} from './ReactFiberContext';
359-
import {peekEntangledActionLane} from './ReactFiberAsyncAction';
360359
import {logUncaughtError} from './ReactFiberErrorLogger';
361360
import {
362361
deleteScheduledGesture,
@@ -779,14 +778,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
779778
transition._updatedFibers.add(fiber);
780779
}
781780

782-
const actionScopeLane = peekEntangledActionLane();
783-
return actionScopeLane !== NoLane
784-
? // We're inside an async action scope. Reuse the same lane.
785-
actionScopeLane
786-
: // We may or may not be inside an async action scope. If we are, this
787-
// is the first update in that scope. Either way, we need to get a
788-
// fresh transition lane.
789-
requestTransitionLane(transition);
781+
return requestTransitionLane(transition);
790782
}
791783

792784
return eventPriorityToLane(resolveUpdatePriority());

0 commit comments

Comments
 (0)