Skip to content

Commit b480865

Browse files
authored
[Fiber] Always flush Default priority in the microtask if a Transition was scheduled (facebook#33186)
Stacked on facebook#33160. The purpose of this is to avoid calling `onDefaultTransitionIndicator` when a Default priority update acts as the loading indicator, but still call it when unrelated Default updates happens nearby. When we schedule Default priority work that gets batched with other events in the same frame more or less. This helps optimize by doing less work. However, that batching means that we can't separate work from one setState from another. If we would consider all Default priority work in a frame when determining whether to show the default we might never show it in cases like when you have a recurring timer updating something. This instead flushes the Default priority work eagerly along with the sync work at the end of the event, if this event scheduled any Transition work. This is then used to determine if the default indicator needs to be shown.
1 parent 62d3f36 commit b480865

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

packages/react-reconciler/src/ReactFiberRootScheduler.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
NoLane,
2727
NoLanes,
2828
SyncLane,
29+
DefaultLane,
2930
getHighestPriorityLane,
3031
getNextLanes,
3132
includesSyncLane,
@@ -261,6 +262,13 @@ function processRootScheduleInMicrotask() {
261262
// render it synchronously anyway. We do this during a popstate event to
262263
// preserve the scroll position of the previous page.
263264
syncTransitionLanes = currentEventTransitionLane;
265+
} else if (enableDefaultTransitionIndicator) {
266+
// If we have a Transition scheduled by this event it might be paired
267+
// with Default lane scheduled loading indicators. To unbatch it from
268+
// other events later on, flush it early to determine whether it
269+
// rendered an indicator. This ensures that setState in default priority
270+
// event doesn't trigger onDefaultTransitionIndicator.
271+
syncTransitionLanes = DefaultLane;
264272
}
265273
}
266274

packages/react-reconciler/src/__tests__/ReactDefaultTransitionIndicator-test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,7 @@ describe('ReactDefaultTransitionIndicator', () => {
109109
expect(root).toMatchRenderedOutput(<div>Hi</div>);
110110

111111
await act(() => {
112-
// TODO: This should not require a discrete update ideally but work for default too.
113-
ReactNoop.discreteUpdates(() => {
114-
update('Loading...');
115-
});
112+
update('Loading...');
116113
React.startTransition(() => {
117114
update('');
118115
root.render(<App>{promiseB}</App>);

0 commit comments

Comments
 (0)