@samitouri / QOS-React / commits / 14a4699ff1

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;