Skip to content

Commit b820aed

Browse files
committed
Add unstable_concurrentUpdatesByDefault
1 parent 933880b commit b820aed

File tree

12 files changed

+94
-10
lines changed

12 files changed

+94
-10
lines changed

packages/react-dom/src/__tests__/ReactDOMRoot-test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ let React = require('react');
1313
let ReactDOM = require('react-dom');
1414
let ReactDOMServer = require('react-dom/server');
1515
let Scheduler = require('scheduler');
16+
let act;
1617

1718
describe('ReactDOMRoot', () => {
1819
let container;
@@ -24,6 +25,7 @@ describe('ReactDOMRoot', () => {
2425
ReactDOM = require('react-dom');
2526
ReactDOMServer = require('react-dom/server');
2627
Scheduler = require('scheduler');
28+
act = require('react-dom/test-utils').unstable_concurrentAct;
2729
});
2830

2931
if (!__EXPERIMENTAL__) {
@@ -316,4 +318,33 @@ describe('ReactDOMRoot', () => {
316318
{withoutStack: true},
317319
);
318320
});
321+
322+
// @gate experimental
323+
it('opts-in to concurrent default updates', async () => {
324+
const root = ReactDOM.unstable_createRoot(container, {
325+
unstable_concurrentUpdatesByDefault: true,
326+
});
327+
328+
function Foo({value}) {
329+
Scheduler.unstable_yieldValue(value);
330+
return <div>{value}</div>;
331+
}
332+
333+
await act(async () => {
334+
root.render(<Foo value="a" />);
335+
});
336+
337+
expect(container.textContent).toEqual('a');
338+
339+
await act(async () => {
340+
root.render(<Foo value="b" />);
341+
342+
expect(Scheduler).toHaveYielded(['a']);
343+
expect(container.textContent).toEqual('a');
344+
345+
expect(Scheduler).toFlushAndYieldThrough(['b']);
346+
expect(container.textContent).toEqual('a');
347+
});
348+
expect(container.textContent).toEqual('b');
349+
});
319350
});

packages/react-dom/src/client/ReactDOMRoot.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type RootOptions = {
2828
...
2929
},
3030
unstable_strictModeLevel?: number,
31+
unstable_concurrentUpdatesByDefault?: boolean,
3132
...
3233
};
3334

@@ -125,13 +126,18 @@ function createRootImpl(
125126
options != null && options.unstable_strictModeLevel != null
126127
? options.unstable_strictModeLevel
127128
: null;
129+
const concurrentUpdatesByDefaultOverride =
130+
options != null && options.unstable_concurrentUpdatesByDefault != null
131+
? options.unstable_concurrentUpdatesByDefault
132+
: null;
128133

129134
const root = createContainer(
130135
container,
131136
tag,
132137
hydrate,
133138
hydrationCallbacks,
134139
strictModeLevelOverride,
140+
concurrentUpdatesByDefaultOverride,
135141
);
136142
markContainerAsRoot(root.current, container);
137143

packages/react-reconciler/src/ReactFiber.new.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import {
6868
ProfileMode,
6969
StrictLegacyMode,
7070
StrictEffectsMode,
71+
ConcurrentUpdatesByDefaultMode,
7172
} from './ReactTypeOfMode';
7273
import {
7374
REACT_FORWARD_REF_TYPE,
@@ -420,6 +421,7 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
420421
export function createHostRootFiber(
421422
tag: RootTag,
422423
strictModeLevelOverride: null | number,
424+
concurrentUpdatesByDefaultOverride: null | boolean,
423425
): Fiber {
424426
let mode;
425427
if (tag === ConcurrentRoot) {
@@ -440,6 +442,9 @@ export function createHostRootFiber(
440442
mode |= StrictLegacyMode;
441443
}
442444
}
445+
if (concurrentUpdatesByDefaultOverride) {
446+
mode |= ConcurrentUpdatesByDefaultMode;
447+
}
443448
} else {
444449
mode = NoMode;
445450
}

packages/react-reconciler/src/ReactFiber.old.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import {
6868
ProfileMode,
6969
StrictLegacyMode,
7070
StrictEffectsMode,
71+
ConcurrentUpdatesByDefaultMode,
7172
} from './ReactTypeOfMode';
7273
import {
7374
REACT_FORWARD_REF_TYPE,
@@ -420,6 +421,7 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
420421
export function createHostRootFiber(
421422
tag: RootTag,
422423
strictModeLevelOverride: null | number,
424+
concurrentUpdatesByDefaultOverride: null | boolean,
423425
): Fiber {
424426
let mode;
425427
if (tag === ConcurrentRoot) {
@@ -440,6 +442,9 @@ export function createHostRootFiber(
440442
mode |= StrictLegacyMode;
441443
}
442444
}
445+
if (concurrentUpdatesByDefaultOverride) {
446+
mode |= ConcurrentUpdatesByDefaultMode;
447+
}
443448
} else {
444449
mode = NoMode;
445450
}

packages/react-reconciler/src/ReactFiberReconciler.new.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,15 @@ export function createContainer(
249249
hydrate: boolean,
250250
hydrationCallbacks: null | SuspenseHydrationCallbacks,
251251
strictModeLevelOverride: null | number,
252+
concurrentUpdatesByDefaultOverride: null | boolean,
252253
): OpaqueRoot {
253254
return createFiberRoot(
254255
containerInfo,
255256
tag,
256257
hydrate,
257258
hydrationCallbacks,
258259
strictModeLevelOverride,
260+
concurrentUpdatesByDefaultOverride,
259261
);
260262
}
261263

packages/react-reconciler/src/ReactFiberReconciler.old.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,15 @@ export function createContainer(
249249
hydrate: boolean,
250250
hydrationCallbacks: null | SuspenseHydrationCallbacks,
251251
strictModeLevelOverride: null | number,
252+
concurrentUpdatesByDefaultOverride: null | boolean,
252253
): OpaqueRoot {
253254
return createFiberRoot(
254255
containerInfo,
255256
tag,
256257
hydrate,
257258
hydrationCallbacks,
258259
strictModeLevelOverride,
260+
concurrentUpdatesByDefaultOverride,
259261
);
260262
}
261263

packages/react-reconciler/src/ReactFiberRoot.new.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export function createFiberRoot(
105105
hydrate: boolean,
106106
hydrationCallbacks: null | SuspenseHydrationCallbacks,
107107
strictModeLevelOverride: null | number,
108+
concurrentUpdatesByDefaultOverride: null | boolean,
108109
): FiberRoot {
109110
const root: FiberRoot = (new FiberRootNode(containerInfo, tag, hydrate): any);
110111
if (enableSuspenseCallback) {
@@ -113,7 +114,11 @@ export function createFiberRoot(
113114

114115
// Cyclic construction. This cheats the type system right now because
115116
// stateNode is any.
116-
const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride);
117+
const uninitializedFiber = createHostRootFiber(
118+
tag,
119+
strictModeLevelOverride,
120+
concurrentUpdatesByDefaultOverride,
121+
);
117122
root.current = uninitializedFiber;
118123
uninitializedFiber.stateNode = root;
119124

packages/react-reconciler/src/ReactFiberRoot.old.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export function createFiberRoot(
105105
hydrate: boolean,
106106
hydrationCallbacks: null | SuspenseHydrationCallbacks,
107107
strictModeLevelOverride: null | number,
108+
concurrentUpdatesByDefaultOverride: null | boolean,
108109
): FiberRoot {
109110
const root: FiberRoot = (new FiberRootNode(containerInfo, tag, hydrate): any);
110111
if (enableSuspenseCallback) {
@@ -113,7 +114,11 @@ export function createFiberRoot(
113114

114115
// Cyclic construction. This cheats the type system right now because
115116
// stateNode is any.
116-
const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride);
117+
const uninitializedFiber = createHostRootFiber(
118+
tag,
119+
strictModeLevelOverride,
120+
concurrentUpdatesByDefaultOverride,
121+
);
117122
root.current = uninitializedFiber;
118123
uninitializedFiber.stateNode = root;
119124

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ import {
107107
StrictLegacyMode,
108108
ProfileMode,
109109
ConcurrentMode,
110+
ConcurrentUpdatesByDefaultMode,
110111
} from './ReactTypeOfMode';
111112
import {
112113
HostRoot,
@@ -440,6 +441,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
440441
if (updateLane !== NoLane) {
441442
if (
442443
enableSyncDefaultUpdates &&
444+
(mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
443445
(updateLane === InputContinuousLane ||
444446
updateLane === InputContinuousHydrationLane)
445447
) {
@@ -457,6 +459,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
457459
const eventLane: Lane = (getCurrentEventPriority(): any);
458460
if (
459461
enableSyncDefaultUpdates &&
462+
(mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
460463
(eventLane === InputContinuousLane ||
461464
eventLane === InputContinuousHydrationLane)
462465
) {
@@ -716,6 +719,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
716719
let newCallbackNode;
717720
if (
718721
enableSyncDefaultUpdates &&
722+
(root.current.mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
719723
(newCallbackPriority === DefaultLane ||
720724
newCallbackPriority === DefaultHydrationLane)
721725
) {
@@ -1058,7 +1062,11 @@ function performSyncWorkOnRoot(root) {
10581062
const finishedWork: Fiber = (root.current.alternate: any);
10591063
root.finishedWork = finishedWork;
10601064
root.finishedLanes = lanes;
1061-
if (enableSyncDefaultUpdates && !includesSomeLane(lanes, SyncLane)) {
1065+
if (
1066+
enableSyncDefaultUpdates &&
1067+
(root.current.mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
1068+
!includesSomeLane(lanes, SyncLane)
1069+
) {
10621070
finishConcurrentRender(root, exitStatus, lanes);
10631071
} else {
10641072
commitRoot(root);

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ import {
107107
StrictLegacyMode,
108108
ProfileMode,
109109
ConcurrentMode,
110+
ConcurrentUpdatesByDefaultMode,
110111
} from './ReactTypeOfMode';
111112
import {
112113
HostRoot,
@@ -440,6 +441,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
440441
if (updateLane !== NoLane) {
441442
if (
442443
enableSyncDefaultUpdates &&
444+
(mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
443445
(updateLane === InputContinuousLane ||
444446
updateLane === InputContinuousHydrationLane)
445447
) {
@@ -457,6 +459,7 @@ export function requestUpdateLane(fiber: Fiber): Lane {
457459
const eventLane: Lane = (getCurrentEventPriority(): any);
458460
if (
459461
enableSyncDefaultUpdates &&
462+
(mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
460463
(eventLane === InputContinuousLane ||
461464
eventLane === InputContinuousHydrationLane)
462465
) {
@@ -716,6 +719,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
716719
let newCallbackNode;
717720
if (
718721
enableSyncDefaultUpdates &&
722+
(root.current.mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
719723
(newCallbackPriority === DefaultLane ||
720724
newCallbackPriority === DefaultHydrationLane)
721725
) {
@@ -1058,7 +1062,11 @@ function performSyncWorkOnRoot(root) {
10581062
const finishedWork: Fiber = (root.current.alternate: any);
10591063
root.finishedWork = finishedWork;
10601064
root.finishedLanes = lanes;
1061-
if (enableSyncDefaultUpdates && !includesSomeLane(lanes, SyncLane)) {
1065+
if (
1066+
enableSyncDefaultUpdates &&
1067+
(root.current.mode & ConcurrentUpdatesByDefaultMode) === NoMode &&
1068+
!includesSomeLane(lanes, SyncLane)
1069+
) {
10621070
finishConcurrentRender(root, exitStatus, lanes);
10631071
} else {
10641072
commitRoot(root);

0 commit comments

Comments
 (0)