Remove allowConcurrentByDefault flag (#30445)
Following https://github.com/facebook/react/pull/30436 Concurrent by default strategy has been unshipped. Here we clean up the `allowConcurrentByDefault` path and related logic/tests. For now, this keeps the `concurrentUpdatesByDefaultOverride` argument in `createContainer` and `createHydrationContainer` and ignores the value to prevent more breaking changes to `react-reconciler` in the RC stage.
Jack Pope committed
Jul 25, 2024 at 11:59 UTC
14a4699ff173936a30ec453f7b94d47105bbb252
16 files changed
+9
-110
packages/react-dom/src/__tests__/ReactDOMRoot-test.js
-35
@@ -17,7 +17,6 @@ let Scheduler = require('scheduler');
17
let act;
18
let useEffect;
19
let assertLog;
20
-let waitFor;
20
let waitForAll;
21
22
describe('ReactDOMRoot', () => {
@@ -36,7 +35,6 @@ describe('ReactDOMRoot', () => {
35
36
const InternalTestUtils = require('internal-test-utils');
37
assertLog = InternalTestUtils.assertLog;
39
- waitFor = InternalTestUtils.waitFor;
38
waitForAll = InternalTestUtils.waitForAll;
39
});
40
@@ -306,39 +304,6 @@ describe('ReactDOMRoot', () => {
304
}).rejects.toThrow('The node to be removed is not a child of this node.');
305
});
306
309
- it('opts-in to concurrent default updates', async () => {
310
- const root = ReactDOMClient.createRoot(container, {
311
- unstable_concurrentUpdatesByDefault: true,
312
- });
313
-
314
- function Foo({value}) {
315
- Scheduler.log(value);
316
- return <div>{value}</div>;
317
- }
318
-
319
- await act(() => {
320
- root.render(<Foo value="a" />);
321
- });
322
-
323
- assertLog(['a']);
324
- expect(container.textContent).toEqual('a');
325
-
326
- await act(async () => {
327
- root.render(<Foo value="b" />);
328
-
329
- assertLog([]);
330
- expect(container.textContent).toEqual('a');
331
-
332
- await waitFor(['b']);
333
- if (gate(flags => flags.allowConcurrentByDefault)) {
334
- expect(container.textContent).toEqual('a');
335
- } else {
336
- expect(container.textContent).toEqual('b');
337
- }
338
- });
339
- expect(container.textContent).toEqual('b');
340
- });
341
-
307
it('unmount is synchronous', async () => {
308
const root = ReactDOMClient.createRoot(container);
309
await act(() => {
packages/react-dom/src/client/ReactDOMRoot.js
+3
-20
@@ -16,10 +16,7 @@ import type {
16
import {isValidContainer} from 'react-dom-bindings/src/client/ReactDOMContainer';
17
import {queueExplicitHydrationTarget} from 'react-dom-bindings/src/events/ReactDOMEventReplaying';
18
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
19
-import {
20
- allowConcurrentByDefault,
21
- enableAsyncActions,
22
-} from 'shared/ReactFeatureFlags';
19
+import {enableAsyncActions} from 'shared/ReactFeatureFlags';
20
21
export type RootType = {
22
render(children: ReactNodeList): void,
@@ -29,7 +26,6 @@ export type RootType = {
26
27
export type CreateRootOptions = {
28
unstable_strictMode?: boolean,
32
- unstable_concurrentUpdatesByDefault?: boolean,
29
unstable_transitionCallbacks?: TransitionTracingCallbacks,
30
identifierPrefix?: string,
31
onUncaughtError?: (
@@ -55,7 +51,6 @@ export type HydrateRootOptions = {
51
onDeleted?: (suspenseNode: Comment) => void,
52
// Options for all roots
53
unstable_strictMode?: boolean,
58
- unstable_concurrentUpdatesByDefault?: boolean,
54
unstable_transitionCallbacks?: TransitionTracingCallbacks,
55
identifierPrefix?: string,
56
onUncaughtError?: (
@@ -173,8 +168,8 @@ export function createRoot(
168
169
warnIfReactDOMContainerInDEV(container);
170
171
+ const concurrentUpdatesByDefaultOverride = false;
172
let isStrictMode = false;
177
- let concurrentUpdatesByDefaultOverride = false;
173
let identifierPrefix = '';
174
let onUncaughtError = defaultOnUncaughtError;
175
let onCaughtError = defaultOnCaughtError;
@@ -206,12 +201,6 @@ export function createRoot(
201
if (options.unstable_strictMode === true) {
202
isStrictMode = true;
203
}
209
- if (
210
- allowConcurrentByDefault &&
211
- options.unstable_concurrentUpdatesByDefault === true
212
- ) {
213
- concurrentUpdatesByDefaultOverride = true;
214
- }
204
if (options.identifierPrefix !== undefined) {
205
identifierPrefix = options.identifierPrefix;
206
}
@@ -289,8 +278,8 @@ export function hydrateRoot(
278
// the hydration callbacks.
279
const hydrationCallbacks = options != null ? options : null;
280
281
+ const concurrentUpdatesByDefaultOverride = false;
282
let isStrictMode = false;
293
- let concurrentUpdatesByDefaultOverride = false;
283
let identifierPrefix = '';
284
let onUncaughtError = defaultOnUncaughtError;
285
let onCaughtError = defaultOnCaughtError;
@@ -301,12 +290,6 @@ export function hydrateRoot(
290
if (options.unstable_strictMode === true) {
291
isStrictMode = true;
292
}
304
- if (
305
- allowConcurrentByDefault &&
306
- options.unstable_concurrentUpdatesByDefault === true
307
- ) {
308
- concurrentUpdatesByDefaultOverride = true;
309
- }
293
if (options.identifierPrefix !== undefined) {
294
identifierPrefix = options.identifierPrefix;
295
}
packages/react-reconciler/src/ReactFiber.js
-10
@@ -31,7 +31,6 @@ import {
31
enableProfilerTimer,
32
enableScopeAPI,
33
enableLegacyHidden,
34
- allowConcurrentByDefault,
34
enableTransitionTracing,
35
enableDebugTracing,
36
enableDO_NOT_USE_disableStrictPassiveEffect,
@@ -85,7 +84,6 @@ import {
84
ProfileMode,
85
StrictLegacyMode,
86
StrictEffectsMode,
88
- ConcurrentUpdatesByDefaultMode,
87
NoStrictPassiveEffectsMode,
88
} from './ReactTypeOfMode';
89
import {
@@ -524,7 +522,6 @@ export function resetWorkInProgress(
522
export function createHostRootFiber(
523
tag: RootTag,
524
isStrictMode: boolean,
527
- concurrentUpdatesByDefaultOverride: null | boolean,
525
): Fiber {
526
let mode;
527
if (disableLegacyMode || tag === ConcurrentRoot) {
@@ -532,13 +529,6 @@ export function createHostRootFiber(
529
if (isStrictMode === true) {
530
mode |= StrictLegacyMode | StrictEffectsMode;
531
}
535
- if (
536
- // Only for internal experiments.
537
- allowConcurrentByDefault &&
538
- concurrentUpdatesByDefaultOverride
539
- ) {
540
- mode |= ConcurrentUpdatesByDefaultMode;
541
- }
532
} else {
533
mode = NoMode;
534
}
packages/react-reconciler/src/ReactFiberLane.js
+1
-15
@@ -19,7 +19,6 @@ export type Lane = number;
19
export type LaneMap<T> = Array<T>;
20
21
import {
22
- allowConcurrentByDefault,
22
enableRetryLaneExpiration,
23
enableSchedulingProfiler,
24
enableTransitionTracing,
@@ -29,7 +28,6 @@ import {
28
retryLaneExpirationMs,
29
} from 'shared/ReactFeatureFlags';
30
import {isDevToolsPresent} from './ReactFiberDevToolsHook';
32
-import {ConcurrentUpdatesByDefaultMode, NoMode} from './ReactTypeOfMode';
31
import {clz32} from './clz32';
32
33
// Lane values below should be kept in sync with getLabelForLane(), used by react-devtools-timeline.
@@ -287,12 +285,7 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
285
export function getEntangledLanes(root: FiberRoot, renderLanes: Lanes): Lanes {
286
let entangledLanes = renderLanes;
287
290
- if (
291
- allowConcurrentByDefault &&
292
- (root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode
293
- ) {
294
- // Do nothing, use the lanes as they were assigned.
295
- } else if ((entangledLanes & InputContinuousLane) !== NoLanes) {
288
+ if ((entangledLanes & InputContinuousLane) !== NoLanes) {
289
// When updates are sync by default, we entangle continuous priority updates
290
// and default updates, so they render in the same batch. The only reason
291
// they use separate lanes is because continuous updates should interrupt
@@ -498,13 +491,6 @@ export function includesOnlyTransitions(lanes: Lanes): boolean {
491
}
492
493
export function includesBlockingLane(root: FiberRoot, lanes: Lanes): boolean {
501
- if (
502
- allowConcurrentByDefault &&
503
- (root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode
504
- ) {
505
- // Concurrent updates by default always use time slicing.
506
- return false;
507
- }
494
const SyncDefaultLanes =
495
InputContinuousHydrationLane |
496
InputContinuousLane |
packages/react-reconciler/src/ReactFiberReconciler.js
+2
-2
@@ -238,6 +238,7 @@ export function createContainer(
238
tag: RootTag,
239
hydrationCallbacks: null | SuspenseHydrationCallbacks,
240
isStrictMode: boolean,
241
+ // TODO: Remove `concurrentUpdatesByDefaultOverride`. It is now ignored.
242
concurrentUpdatesByDefaultOverride: null | boolean,
243
identifierPrefix: string,
244
onUncaughtError: (
@@ -266,7 +267,6 @@ export function createContainer(
267
initialChildren,
268
hydrationCallbacks,
269
isStrictMode,
269
- concurrentUpdatesByDefaultOverride,
270
identifierPrefix,
271
onUncaughtError,
272
onCaughtError,
@@ -284,6 +284,7 @@ export function createHydrationContainer(
284
tag: RootTag,
285
hydrationCallbacks: null | SuspenseHydrationCallbacks,
286
isStrictMode: boolean,
287
+ // TODO: Remove `concurrentUpdatesByDefaultOverride`. It is now ignored.
288
concurrentUpdatesByDefaultOverride: null | boolean,
289
identifierPrefix: string,
290
onUncaughtError: (
@@ -312,7 +313,6 @@ export function createHydrationContainer(
313
initialChildren,
314
hydrationCallbacks,
315
isStrictMode,
315
- concurrentUpdatesByDefaultOverride,
316
identifierPrefix,
317
onUncaughtError,
318
onCaughtError,
packages/react-reconciler/src/ReactFiberRoot.js
+1
-6
@@ -147,7 +147,6 @@ export function createFiberRoot(
147
initialChildren: ReactNodeList,
148
hydrationCallbacks: null | SuspenseHydrationCallbacks,
149
isStrictMode: boolean,
150
- concurrentUpdatesByDefaultOverride: null | boolean,
150
// TODO: We have several of these arguments that are conceptually part of the
151
// host config, but because they are passed in at runtime, we have to thread
152
// them through the root constructor. Perhaps we should put them all into a
@@ -192,11 +191,7 @@ export function createFiberRoot(
191
192
// Cyclic construction. This cheats the type system right now because
193
// stateNode is any.
195
- const uninitializedFiber = createHostRootFiber(
196
- tag,
197
- isStrictMode,
198
- concurrentUpdatesByDefaultOverride,
199
- );
194
+ const uninitializedFiber = createHostRootFiber(tag, isStrictMode);
195
root.current = uninitializedFiber;
196
uninitializedFiber.stateNode = root;
197
packages/react-reconciler/src/ReactTypeOfMode.js
-1
@@ -16,5 +16,4 @@ export const ProfileMode = /* */ 0b0000010;
16
export const DebugTracingMode = /* */ 0b0000100;
17
export const StrictLegacyMode = /* */ 0b0001000;
18
export const StrictEffectsMode = /* */ 0b0010000;
19
-export const ConcurrentUpdatesByDefaultMode = /* */ 0b0100000;
19
export const NoStrictPassiveEffectsMode = /* */ 0b1000000;
packages/react-test-renderer/src/ReactTestRenderer.js
+1
-10
@@ -56,7 +56,6 @@ import {checkPropStringCoercion} from 'shared/CheckStringCoercion';
56
import {getPublicInstance} from './ReactFiberConfigTestHost';
57
import {ConcurrentRoot, LegacyRoot} from 'react-reconciler/src/ReactRootTags';
58
import {
59
- allowConcurrentByDefault,
59
enableReactTestRendererWarning,
60
disableLegacyMode,
61
} from 'shared/ReactFeatureFlags';
@@ -70,7 +69,6 @@ type TestRendererOptions = {
69
createNodeMock: (element: React$Element<any>) => any,
70
unstable_isConcurrent: boolean,
71
unstable_strictMode: boolean,
73
- unstable_concurrentUpdatesByDefault: boolean,
72
...
73
};
74
@@ -486,7 +484,6 @@ function create(
484
global.IS_REACT_NATIVE_TEST_ENVIRONMENT !== true;
485
let isConcurrent = isConcurrentOnly;
486
let isStrictMode = false;
489
- let concurrentUpdatesByDefault = null;
487
if (typeof options === 'object' && options !== null) {
488
if (typeof options.createNodeMock === 'function') {
489
// $FlowFixMe[incompatible-type] found when upgrading Flow
@@ -498,12 +495,6 @@ function create(
495
if (options.unstable_strictMode === true) {
496
isStrictMode = true;
497
}
501
- if (allowConcurrentByDefault) {
502
- if (options.unstable_concurrentUpdatesByDefault !== undefined) {
503
- concurrentUpdatesByDefault =
504
- options.unstable_concurrentUpdatesByDefault;
505
- }
506
- }
498
}
499
let container = {
500
children: ([]: Array<Instance | TextInstance>),
@@ -515,7 +506,7 @@ function create(
506
isConcurrent ? ConcurrentRoot : LegacyRoot,
507
null,
508
isStrictMode,
518
- concurrentUpdatesByDefault,
509
+ false,
510
'',
511
defaultOnUncaughtError,
512
defaultOnCaughtError,
packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js
+1
-1
@@ -93,7 +93,7 @@ describe('ReactTestRenderer', () => {
93
tag,
94
null,
95
expect.anything(),
96
- null,
96
+ false,
97
expect.anything(),
98
expect.anything(),
99
expect.anything(),
packages/shared/ReactFeatureFlags.js
-3
@@ -217,9 +217,6 @@ export const enableUseDeferredValueInitialArg = true;
217
// when we plan to enable them.
218
// -----------------------------------------------------------------------------
219
220
-// Adds an opt-in to time slicing for updates that aren't wrapped in startTransition.
221
-export const allowConcurrentByDefault = false;
222
-
220
// -----------------------------------------------------------------------------
221
// React DOM Chopping Block
222
//
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -27,7 +27,6 @@ export const {
27
} = dynamicFlags;
28
29
// The rest of the flags are static for better dead code elimination.
30
-export const allowConcurrentByDefault = false;
30
export const consoleManagedByDevToolsDuringStrictMode = true;
31
export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
32
export const disableClientCache = true;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -19,7 +19,6 @@ export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
19
// -----------------------------------------------------------------------------
20
// All other flags
21
// -----------------------------------------------------------------------------
22
-export const allowConcurrentByDefault = false;
22
export const alwaysThrottleRetries = false;
23
export const consoleManagedByDevToolsDuringStrictMode = true;
24
export const disableClientCache = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -53,7 +53,6 @@ export const transitionLaneExpirationMs = 5000;
53
export const disableSchedulerTimeoutInWorkLoop = false;
54
export const enableLazyContextPropagation = false;
55
export const enableLegacyHidden = false;
56
-export const allowConcurrentByDefault = false;
56
57
export const consoleManagedByDevToolsDuringStrictMode = false;
58
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
-1
@@ -10,7 +10,6 @@
10
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11
import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
12
13
-export const allowConcurrentByDefault = true;
13
export const alwaysThrottleRetries = false;
14
export const consoleManagedByDevToolsDuringStrictMode = false;
15
export const debugRenderPhaseSideEffectsForStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -56,7 +56,6 @@ export const transitionLaneExpirationMs = 5000;
56
export const disableSchedulerTimeoutInWorkLoop = false;
57
export const enableLazyContextPropagation = false;
58
export const enableLegacyHidden = false;
59
-export const allowConcurrentByDefault = true;
59
60
export const consoleManagedByDevToolsDuringStrictMode = false;
61
packages/shared/forks/ReactFeatureFlags.www.js
-2
@@ -96,8 +96,6 @@ export const enableRefAsProp = true;
96
97
export const disableTextareaChildren = __EXPERIMENTAL__;
98
99
-export const allowConcurrentByDefault = true;
100
-
99
export const consoleManagedByDevToolsDuringStrictMode = true;
100
101
export const enableFizzExternalRuntime = true;