diff --git a/packages/react-art/src/__tests__/ReactART-test.js b/packages/react-art/src/__tests__/ReactART-test.js index 9f73006d0201a..47b5958cf4c9c 100644 --- a/packages/react-art/src/__tests__/ReactART-test.js +++ b/packages/react-art/src/__tests__/ReactART-test.js @@ -364,7 +364,7 @@ describe('ReactART', () => { expect(onClick2).toBeCalled(); }); - // @gate !enableSyncDefaultUpdates + // @gate forceConcurrentByDefaultForTesting it('can concurrently render with a "primary" renderer while sharing context', async () => { const CurrentRendererContext = React.createContext(null); diff --git a/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js b/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js index 3300dc1bb35c3..6b445f9cf8d61 100644 --- a/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js @@ -312,10 +312,10 @@ describe('ReactDOMNativeEventHeuristic-test', () => { expect(container.textContent).toEqual('not hovered'); await waitFor(['hovered']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - expect(container.textContent).toEqual('hovered'); - } else { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { expect(container.textContent).toEqual('not hovered'); + } else { + expect(container.textContent).toEqual('hovered'); } }); expect(container.textContent).toEqual('hovered'); diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index ab09c63a7bcb9..4384bc03651bc 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -2036,13 +2036,13 @@ describe('ReactDOMServerPartialHydration', () => { suspend = true; await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - await waitFor(['Before', 'After']); - } else { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { await waitFor(['Before']); // This took a long time to render. Scheduler.unstable_advanceTime(1000); await waitFor(['After']); + } else { + await waitFor(['Before', 'After']); } // This will cause us to skip the second row completely. diff --git a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js index 4b6c5717fa29b..1a1769e82c07e 100644 --- a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js +++ b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js @@ -1984,13 +1984,9 @@ describe('DOMPluginEventSystem', () => { log.length = 0; // Increase counter - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Yield before committing await waitFor(['Test']); diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 7eefefa1c4d14..84ef41f4fb97b 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -33,7 +33,7 @@ import { enableProfilerTimer, enableScopeAPI, enableLegacyHidden, - enableSyncDefaultUpdates, + forceConcurrentByDefaultForTesting, allowConcurrentByDefault, enableTransitionTracing, enableDebugTracing, @@ -460,10 +460,13 @@ export function createHostRootFiber( } if ( // We only use this flag for our repo tests to check both behaviors. - // TODO: Flip this flag and rename it something like "forceConcurrentByDefaultForTesting" - !enableSyncDefaultUpdates || + forceConcurrentByDefaultForTesting + ) { + mode |= ConcurrentUpdatesByDefaultMode; + } else if ( // Only for internal experiments. - (allowConcurrentByDefault && concurrentUpdatesByDefaultOverride) + allowConcurrentByDefault && + concurrentUpdatesByDefaultOverride ) { mode |= ConcurrentUpdatesByDefaultMode; } diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js index 653bc304600bb..cd09ca347885b 100644 --- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js +++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js @@ -125,7 +125,22 @@ describe('ReactExpiration', () => { } it('increases priority of updates as time progresses', async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { + ReactNoop.render(); + expect(ReactNoop).toMatchRenderedOutput(null); + + // Nothing has expired yet because time hasn't advanced. + flushNextRenderIfExpired(); + expect(ReactNoop).toMatchRenderedOutput(null); + // Advance time a bit, but not enough to expire the low pri update. + ReactNoop.expire(4500); + flushNextRenderIfExpired(); + expect(ReactNoop).toMatchRenderedOutput(null); + // Advance by another second. Now the update should expire and flush. + ReactNoop.expire(500); + flushNextRenderIfExpired(); + expect(ReactNoop).toMatchRenderedOutput(); + } else { ReactNoop.render(); React.startTransition(() => { ReactNoop.render(); @@ -147,21 +162,6 @@ describe('ReactExpiration', () => { ReactNoop.expire(500); await unstable_waitForExpired(['Step 2']); expect(ReactNoop).toMatchRenderedOutput('Step 2'); - } else { - ReactNoop.render(); - expect(ReactNoop).toMatchRenderedOutput(null); - - // Nothing has expired yet because time hasn't advanced. - flushNextRenderIfExpired(); - expect(ReactNoop).toMatchRenderedOutput(null); - // Advance time a bit, but not enough to expire the low pri update. - ReactNoop.expire(4500); - flushNextRenderIfExpired(); - expect(ReactNoop).toMatchRenderedOutput(null); - // Advance by another second. Now the update should expire and flush. - ReactNoop.expire(500); - flushNextRenderIfExpired(); - expect(ReactNoop).toMatchRenderedOutput(); } }); @@ -187,13 +187,9 @@ describe('ReactExpiration', () => { // First, show what happens for updates in two separate events. // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Advance the timer. Scheduler.unstable_advanceTime(2000); // Partially flush the first update, then interrupt it. @@ -248,13 +244,10 @@ describe('ReactExpiration', () => { // First, show what happens for updates in two separate events. // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); + // Advance the timer. Scheduler.unstable_advanceTime(2000); // Partially flush the first update, then interrupt it. @@ -320,13 +313,10 @@ describe('ReactExpiration', () => { } // Initial mount - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); + await waitForAll([ 'initial [A] [render]', 'initial [B] [render]', @@ -339,13 +329,10 @@ describe('ReactExpiration', () => { ]); // Partial update - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - subscribers.forEach(s => s.setState({text: '1'})); - }); - } else { + React.startTransition(() => { subscribers.forEach(s => s.setState({text: '1'})); - } + }); + await waitFor(['1 [A] [render]', '1 [B] [render]']); // Before the update can finish, update again. Even though no time has @@ -371,13 +358,9 @@ describe('ReactExpiration', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); await waitFor(['A']); await waitFor(['B']); @@ -404,13 +387,9 @@ describe('ReactExpiration', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); await waitFor(['A']); await waitFor(['B']); @@ -429,7 +408,26 @@ describe('ReactExpiration', () => { jest.resetModules(); Scheduler = require('scheduler'); - if (gate(flags => flags.enableSyncDefaultUpdates)) { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { + // Before importing the renderer, advance the current time by a number + // larger than the maximum allowed for bitwise operations. + const maxSigned31BitInt = 1073741823; + Scheduler.unstable_advanceTime(maxSigned31BitInt * 100); + // Now import the renderer. On module initialization, it will read the + // current time. + ReactNoop = require('react-noop-renderer'); + ReactNoop.render('Hi'); + + // The update should not have expired yet. + flushNextRenderIfExpired(); + await waitFor([]); + expect(ReactNoop).toMatchRenderedOutput(null); + // Advance the time some more to expire the update. + Scheduler.unstable_advanceTime(10000); + flushNextRenderIfExpired(); + await waitFor([]); + expect(ReactNoop).toMatchRenderedOutput('Hi'); + } else { const InternalTestUtils = require('internal-test-utils'); waitFor = InternalTestUtils.waitFor; assertLog = InternalTestUtils.assertLog; @@ -446,14 +444,10 @@ describe('ReactExpiration', () => { React = require('react'); ReactNoop.render(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - await waitFor(['Step 1']); - } else { - ReactNoop.render('Hi'); - } + React.startTransition(() => { + ReactNoop.render(); + }); + await waitFor(['Step 1']); // The update should not have expired yet. await unstable_waitForExpired([]); @@ -464,25 +458,6 @@ describe('ReactExpiration', () => { Scheduler.unstable_advanceTime(10000); await unstable_waitForExpired(['Step 2']); expect(ReactNoop).toMatchRenderedOutput('Step 2'); - } else { - // Before importing the renderer, advance the current time by a number - // larger than the maximum allowed for bitwise operations. - const maxSigned31BitInt = 1073741823; - Scheduler.unstable_advanceTime(maxSigned31BitInt * 100); - // Now import the renderer. On module initialization, it will read the - // current time. - ReactNoop = require('react-noop-renderer'); - ReactNoop.render('Hi'); - - // The update should not have expired yet. - flushNextRenderIfExpired(); - await waitFor([]); - expect(ReactNoop).toMatchRenderedOutput(null); - // Advance the time some more to expire the update. - Scheduler.unstable_advanceTime(10000); - flushNextRenderIfExpired(); - await waitFor([]); - expect(ReactNoop).toMatchRenderedOutput('Hi'); } }); @@ -494,13 +469,10 @@ describe('ReactExpiration', () => { // Before scheduling an update, advance the current time. Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render('Hi'); - }); - } else { + React.startTransition(() => { ReactNoop.render('Hi'); - } + }); + await unstable_waitForExpired([]); expect(ReactNoop).toMatchRenderedOutput(null); @@ -541,13 +513,9 @@ describe('ReactExpiration', () => { // First demonstrate what happens when there's no starvation await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateNormalPri(); - }); - } else { + React.startTransition(() => { updateNormalPri(); - } + }); await waitFor(['Sync pri: 0']); updateSyncPri(); assertLog(['Sync pri: 1', 'Normal pri: 0']); @@ -565,13 +533,9 @@ describe('ReactExpiration', () => { // Do the same thing, but starve the first update await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateNormalPri(); - }); - } else { + React.startTransition(() => { updateNormalPri(); - } + }); await waitFor(['Sync pri: 1']); // This time, a lot of time has elapsed since the normal pri update diff --git a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js index 57e2aad2e3334..e2d9ba76660f9 100644 --- a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js +++ b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js @@ -49,13 +49,9 @@ describe('ReactFlushSync', () => { const root = ReactNoop.createRoot(); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // This will yield right before the passive effect fires await waitForPaint(['0, 0']); diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js index 5609b462258ad..8e32084cf7c49 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js @@ -179,15 +179,10 @@ describe('ReactHooksWithNoopRenderer', () => { // Schedule some updates await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - counter.current.updateCount(1); - counter.current.updateCount(count => count + 10); - }); - } else { + React.startTransition(() => { counter.current.updateCount(1); counter.current.updateCount(count => count + 10); - } + }); // Partially flush without committing await waitFor(['Count: 11']); @@ -800,13 +795,9 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.discreteUpdates(() => { setRow(5); }); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setRow(20); - }); - } else { + React.startTransition(() => { setRow(20); - } + }); }); assertLog(['Up', 'Down']); expect(root).toMatchRenderedOutput(); @@ -1318,13 +1309,9 @@ describe('ReactHooksWithNoopRenderer', () => { ]); // Schedule another update for children, and partially process it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setChildStates.forEach(setChildState => setChildState(2)); - }); - } else { + React.startTransition(() => { setChildStates.forEach(setChildState => setChildState(2)); - } + }); await waitFor(['Child one render']); // Schedule unmount for the parent that unmounts children with pending update. @@ -1598,29 +1585,21 @@ describe('ReactHooksWithNoopRenderer', () => { expect(ReactNoop).toMatchRenderedOutput(); // Rendering again should flush the previous commit's effects - if (gate(flags => flags.enableSyncDefaultUpdates)) { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { + ReactNoop.render(, () => + Scheduler.log('Sync effect'), + ); + } else { React.startTransition(() => { ReactNoop.render(, () => Scheduler.log('Sync effect'), ); }); - } else { - ReactNoop.render(, () => - Scheduler.log('Sync effect'), - ); } await waitFor(['Schedule update [0]', 'Count: 0']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - expect(ReactNoop).toMatchRenderedOutput(); - await waitFor([ - 'Count: 0', - 'Sync effect', - 'Schedule update [1]', - 'Count: 1', - ]); - } else { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { expect(ReactNoop).toMatchRenderedOutput( , ); @@ -1630,6 +1609,14 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.flushPassiveEffects(); assertLog(['Schedule update [1]']); await waitForAll(['Count: 1']); + } else { + expect(ReactNoop).toMatchRenderedOutput(); + await waitFor([ + 'Count: 0', + 'Sync effect', + 'Schedule update [1]', + 'Count: 1', + ]); } expect(ReactNoop).toMatchRenderedOutput(); diff --git a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js index 4a51c737350d6..13f904bf9d014 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js @@ -75,13 +75,9 @@ describe('ReactIncremental', () => { return [, ]; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(, () => Scheduler.log('callback')); - }); - } else { + React.startTransition(() => { ReactNoop.render(, () => Scheduler.log('callback')); - } + }); // Do one step of work. await waitFor(['Foo']); @@ -168,26 +164,18 @@ describe('ReactIncremental', () => { ReactNoop.render(); await waitForAll(['Foo', 'Bar', 'Bar']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush part of the work await waitFor(['Foo', 'Bar']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render(null)); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush part of the new work await waitFor(['Foo', 'Bar']); @@ -221,17 +209,7 @@ describe('ReactIncremental', () => { ReactNoop.render(); await waitForAll([]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - inst.setState( - () => { - Scheduler.log('setState1'); - return {text: 'bar'}; - }, - () => Scheduler.log('callback1'), - ); - }); - } else { + React.startTransition(() => { inst.setState( () => { Scheduler.log('setState1'); @@ -239,24 +217,14 @@ describe('ReactIncremental', () => { }, () => Scheduler.log('callback1'), ); - } + }); // Flush part of the work await waitFor(['setState1']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render()); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - inst.setState( - () => { - Scheduler.log('setState2'); - return {text2: 'baz'}; - }, - () => Scheduler.log('callback2'), - ); - }); - } else { + React.startTransition(() => { inst.setState( () => { Scheduler.log('setState2'); @@ -264,7 +232,7 @@ describe('ReactIncremental', () => { }, () => Scheduler.log('callback2'), ); - } + }); // Flush the rest of the work which now includes the low priority await waitForAll(['setState1', 'setState2', 'callback1', 'callback2']); @@ -1825,18 +1793,7 @@ describe('ReactIncremental', () => { 'ShowLocale {"locale":"de"}', 'ShowBoth {"locale":"de"}', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - -
- -
-
, - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -1845,7 +1802,7 @@ describe('ReactIncremental', () => { , ); - } + }); await waitFor(['Intl {}']); ReactNoop.render( @@ -1977,22 +1934,7 @@ describe('ReactIncremental', () => { } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -2005,7 +1947,8 @@ describe('ReactIncremental', () => { , ); - } + }); + await waitFor([ 'Intl {}', 'ShowLocale {"locale":"fr"}', @@ -2682,13 +2625,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor(['Parent: 1']); // Interrupt at same priority @@ -2708,13 +2647,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor(['Parent: 1']); // Interrupt at lower priority @@ -2735,13 +2670,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor(['Parent: 1']); // Interrupt at higher priority diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js index ac606f1e6870a..2f6b225f2f60e 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js @@ -97,25 +97,7 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('oops!'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> @@ -131,7 +113,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - } + }); // Start rendering asynchronously await waitFor([ @@ -214,25 +196,7 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('oops!'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> @@ -248,7 +212,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - } + }); // Start rendering asynchronously await waitFor([ @@ -416,13 +380,9 @@ describe('ReactIncrementalErrorHandling', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(, () => Scheduler.log('commit')); - }); - } else { + React.startTransition(() => { ReactNoop.render(, () => Scheduler.log('commit')); - } + }); // Render the bad component asynchronously await waitFor(['Parent', 'BadRender']); @@ -458,13 +418,9 @@ describe('ReactIncrementalErrorHandling', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part of the tree await waitFor(['A', 'B']); @@ -595,21 +551,13 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('Hello'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( , ); - } + }); await waitFor(['ErrorBoundary render success']); expect(ReactNoop).toMatchRenderedOutput(null); @@ -783,21 +731,13 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('Hello'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( , ); - } + }); await waitFor(['RethrowErrorBoundary render']); @@ -1856,13 +1796,9 @@ describe('ReactIncrementalErrorHandling', () => { } await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Render past the component that throws, then yield. await waitFor(['Oops']); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js index 2ae5002b97f74..cffd690e64715 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js @@ -65,13 +65,9 @@ describe('ReactIncrementalReflection', () => { return ; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part way through but don't yet commit the updates. await waitFor(['componentWillMount: false']); @@ -117,13 +113,9 @@ describe('ReactIncrementalReflection', () => { expect(instances[0]._isMounted()).toBe(true); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part way through but don't yet commit the updates so it is not // fully unmounted yet. await waitFor(['Other']); @@ -191,13 +183,9 @@ describe('ReactIncrementalReflection', () => { return [, ]; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush past Component but don't complete rendering everything yet. await waitFor([['componentWillMount', null], 'render', 'render sibling']); @@ -227,13 +215,9 @@ describe('ReactIncrementalReflection', () => { // The next step will render a new host node but won't get committed yet. // We expect this to mutate the original Fiber. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor([ ['componentWillUpdate', hostSpan], 'render', @@ -254,13 +238,9 @@ describe('ReactIncrementalReflection', () => { expect(ReactNoop.findInstance(classInstance)).toBe(hostDiv); // Render to null but don't commit it yet. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor([ ['componentWillUpdate', hostDiv], 'render', diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js index 6a1f16fdc2c7d..8c00ec741206e 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js @@ -115,15 +115,10 @@ describe('ReactIncrementalScheduling', () => { // Schedule deferred work in the reverse order await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.renderToRootWithID(, 'c'); - ReactNoop.renderToRootWithID(, 'b'); - }); - } else { + React.startTransition(() => { ReactNoop.renderToRootWithID(, 'c'); ReactNoop.renderToRootWithID(, 'b'); - } + }); // Ensure it starts in the order it was scheduled await waitFor(['c:2']); @@ -132,13 +127,9 @@ describe('ReactIncrementalScheduling', () => { expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2'); // Schedule last bit of work, it will get processed the last - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.renderToRootWithID(, 'a'); - }); - } else { + React.startTransition(() => { ReactNoop.renderToRootWithID(, 'a'); - } + }); // Keep performing work in the order it was scheduled await waitFor(['b:2']); @@ -189,13 +180,9 @@ describe('ReactIncrementalScheduling', () => { } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render without committing await waitFor(['render: 0']); @@ -209,13 +196,9 @@ describe('ReactIncrementalScheduling', () => { 'componentDidUpdate: 1', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - instance.setState({tick: 2}); - }); - } else { + React.startTransition(() => { instance.setState({tick: 2}); - } + }); await waitFor(['render: 2']); expect(ReactNoop.flushNextYield()).toEqual([ 'componentDidUpdate: 2', @@ -316,13 +299,9 @@ describe('ReactIncrementalScheduling', () => { return ; } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete all the work, but not enough to // commit it. diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js index 5df785b7e03cd..b47897e54d92e 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js @@ -464,13 +464,9 @@ describe('ReactIncrementalSideEffects', () => { , ); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush some of the work without committing await waitFor(['Foo', 'Bar']); @@ -703,13 +699,9 @@ describe('ReactIncrementalSideEffects', () => { Scheduler.log('Foo ' + props.step); return ; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete the tree without committing it await waitFor(['Foo 1']); expect(ReactNoop.getChildrenAsJSX()).toEqual(null); @@ -718,26 +710,18 @@ describe('ReactIncrementalSideEffects', () => { await waitForPaint([]); expect(ReactNoop.getChildrenAsJSX()).toEqual(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete the tree without committing it await waitFor(['Foo 2']); expect(ReactNoop.getChildrenAsJSX()).toEqual(); // This time, before we commit the tree, we update the root component with // new props - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(ReactNoop.getChildrenAsJSX()).toEqual(); // Now let's commit. We already had a commit that was pending, which will // render 2. diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js index 13488a7c899de..f3d5cbc675c52 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js @@ -158,7 +158,9 @@ describe('ReactIncrementalUpdates', () => { // Schedule some async updates if ( gate( - flags => flags.enableSyncDefaultUpdates || flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting || + flags.enableUnifiedSyncLane, ) ) { React.startTransition(() => { @@ -189,7 +191,9 @@ describe('ReactIncrementalUpdates', () => { // The sync updates should have flushed, but not the async ones. if ( gate( - flags => flags.enableSyncDefaultUpdates && flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting && + flags.enableUnifiedSyncLane, ) ) { assertLog(['d', 'e', 'f']); @@ -205,7 +209,9 @@ describe('ReactIncrementalUpdates', () => { // is deterministic. if ( gate( - flags => flags.enableSyncDefaultUpdates && !flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting && + !flags.enableUnifiedSyncLane, ) ) { await waitForAll([ @@ -263,7 +269,9 @@ describe('ReactIncrementalUpdates', () => { // Schedule some async updates if ( gate( - flags => flags.enableSyncDefaultUpdates || flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting || + flags.enableUnifiedSyncLane, ) ) { React.startTransition(() => { @@ -297,7 +305,9 @@ describe('ReactIncrementalUpdates', () => { // The sync updates should have flushed, but not the async ones. if ( gate( - flags => flags.enableSyncDefaultUpdates && flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting && + flags.enableUnifiedSyncLane, ) ) { assertLog(['d', 'e', 'f']); @@ -312,7 +322,9 @@ describe('ReactIncrementalUpdates', () => { // is deterministic. if ( gate( - flags => flags.enableSyncDefaultUpdates && !flags.enableUnifiedSyncLane, + flags => + !flags.forceConcurrentByDefaultForTesting && + !flags.enableUnifiedSyncLane, ) ) { await waitForAll([ @@ -543,13 +555,9 @@ describe('ReactIncrementalUpdates', () => { } await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); assertLog([]); await waitForAll([ 'Render: 0', @@ -560,13 +568,9 @@ describe('ReactIncrementalUpdates', () => { ]); Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setCount(2); - }); - } else { + React.startTransition(() => { setCount(2); - } + }); // The transition should not have expired, so we should be able to // partially render it. await waitFor(['Render: 2']); @@ -583,18 +587,7 @@ describe('ReactIncrementalUpdates', () => { Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> @@ -603,7 +596,7 @@ describe('ReactIncrementalUpdates', () => { , ); - } + }); // The transition should not have expired, so we should be able to // partially render it. await waitFor(['A']); @@ -612,18 +605,7 @@ describe('ReactIncrementalUpdates', () => { }); it('regression: does not expire soon due to previous expired work', async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> @@ -632,7 +614,8 @@ describe('ReactIncrementalUpdates', () => { , ); - } + }); + await waitFor(['A']); // This will expire the rest of the update Scheduler.unstable_advanceTime(10000); @@ -643,18 +626,7 @@ describe('ReactIncrementalUpdates', () => { Scheduler.unstable_advanceTime(10000); // Now do another transition. This one should not expire. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> @@ -663,7 +635,8 @@ describe('ReactIncrementalUpdates', () => { , ); - } + }); + // The transition should not have expired, so we should be able to // partially render it. await waitFor(['A']); @@ -703,13 +676,9 @@ describe('ReactIncrementalUpdates', () => { expect(root).toMatchRenderedOutput(null); await act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - pushToLog('A'); - }); - } else { + React.startTransition(() => { pushToLog('A'); - } + }); ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), @@ -768,13 +737,9 @@ describe('ReactIncrementalUpdates', () => { expect(root).toMatchRenderedOutput(null); await act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - pushToLog('A'); - }); - } else { + React.startTransition(() => { pushToLog('A'); - } + }); ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), ); diff --git a/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js index 61e8985ebb0a0..7e676861b5d31 100644 --- a/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js +++ b/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js @@ -65,25 +65,17 @@ describe('ReactInterleavedUpdates', () => { expect(root).toMatchRenderedOutput('000'); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateChildren(1); - }); - } else { + React.startTransition(() => { updateChildren(1); - } + }); // Partially render the children. Only the first one. await waitFor([1]); // In an interleaved event, schedule an update on each of the children. // Including the two that haven't rendered yet. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateChildren(2); - }); - } else { + React.startTransition(() => { updateChildren(2); - } + }); // We should continue rendering without including the interleaved updates. await waitForPaint([1, 1]); @@ -94,7 +86,7 @@ describe('ReactInterleavedUpdates', () => { expect(root).toMatchRenderedOutput('222'); }); - // @gate !enableSyncDefaultUpdates + // @gate forceConcurrentByDefaultForTesting test('low priority update during an interleaved event is not processed during the current render', async () => { // Same as previous test, but the interleaved update is lower priority than // the in-progress render. diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js index b6be6309e00c1..288eb5734d359 100644 --- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js +++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js @@ -885,13 +885,9 @@ describe('ReactNewContext', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render past the Provider, but don't commit yet await waitFor(['Foo']); @@ -934,13 +930,9 @@ describe('ReactNewContext', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitForAll(['Foo', 'Foo']); // Get a new copy of ReactNoop diff --git a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js index f67e2549862bd..17067638ac811 100644 --- a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js @@ -109,13 +109,9 @@ describe('ReactSchedulerIntegration', () => { scheduleCallback(NormalPriority, () => Scheduler.log('C')); // Schedule a React render. React will request a paint after committing it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render('Update'); - }); - } else { + React.startTransition(() => { root.render('Update'); - } + }); // Perform just a little bit of work. By now, the React task will have // already been scheduled, behind A, B, and C. diff --git a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js index aff316ae10965..6e347b900f655 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js @@ -224,19 +224,7 @@ describe('ReactSuspense', () => { expect(root).toMatchRenderedOutput('Initial'); // The update will suspend. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update( - <> - }> - - - - - , - ); - }); - } else { + React.startTransition(() => { root.update( <> }> @@ -246,7 +234,7 @@ describe('ReactSuspense', () => { , ); - } + }); // Yield past the Suspense boundary but don't complete the last sibling. await waitFor(['Suspend!', 'Loading...', 'After Suspense']); @@ -339,7 +327,7 @@ describe('ReactSuspense', () => { expect(root).toMatchRenderedOutput('AB'); }); - // @gate !enableSyncDefaultUpdates + // @gate forceConcurrentByDefaultForTesting it( 'interrupts current render when something suspends with a ' + "delay and we've already skipped over a lower priority update in " + diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js index bbb0b2912b1cc..42e758b4da8df 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js @@ -2497,13 +2497,9 @@ describe('ReactSuspenseList', () => { await act(async () => { // Add a few items at the end. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateLowPri(true); - }); - } else { + React.startTransition(() => { updateLowPri(true); - } + }); // Flush partially through. await waitFor(['B', 'C']); @@ -2639,13 +2635,9 @@ describe('ReactSuspenseList', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor(['App', 'First Pass A', 'Mount A', 'A']); expect(ReactNoop).toMatchRenderedOutput(A); @@ -2707,13 +2699,9 @@ describe('ReactSuspenseList', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitFor([ 'App', diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js index 1b05f8a2f4f50..d93c8bcf606ab 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js @@ -681,35 +681,23 @@ describe('ReactSuspenseWithNoopRenderer', () => { // Schedule an update at several distinct expiration times await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); await waitFor(['Sibling']); interrupt(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); await waitFor(['Sibling']); interrupt(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); await waitFor(['Sibling']); interrupt(); @@ -865,18 +853,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { ); await waitForAll([]); expect(root).toMatchRenderedOutput(null); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render( - <> - }> - - - - , - ); - }); - } else { + React.startTransition(() => { root.render( <> }> @@ -885,7 +862,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { , ); - } + }); await waitFor(['Suspend! [Async]']); await resolveText('Async'); @@ -2256,26 +2233,26 @@ describe('ReactSuspenseWithNoopRenderer', () => { await waitForAll(['Foo', 'A']); expect(ReactNoop).toMatchRenderedOutput(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { + ReactNoop.render(); + } else { React.startTransition(() => { ReactNoop.render(); }); - } else { - ReactNoop.render(); } await waitForAll(['Foo', 'A', 'Suspend! [B]', 'Loading B...']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Transitions never fall back. - expect(ReactNoop).toMatchRenderedOutput(); - } else { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { expect(ReactNoop).toMatchRenderedOutput( <> , ); + } else { + // Transitions never fall back. + expect(ReactNoop).toMatchRenderedOutput(); } }); @@ -2301,13 +2278,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { await waitForAll(['Foo', 'A']); expect(ReactNoop).toMatchRenderedOutput(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); await waitForAll([ 'Foo', @@ -2322,12 +2295,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { Scheduler.unstable_advanceTime(600); await advanceTimers(600); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Transitions never fall back. - expect(ReactNoop).toMatchRenderedOutput(); - } else { - expect(ReactNoop).toMatchRenderedOutput(); - } + expect(ReactNoop).toMatchRenderedOutput(); }); describe('startTransition', () => { @@ -3537,7 +3505,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { }); // @gate enableLegacyCache - // @gate !enableSyncDefaultUpdates + // @gate forceConcurrentByDefaultForTesting it('regression: ping at high priority causes update to be dropped', async () => { const {useState, useTransition} = React; diff --git a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js index 4ae03ac8250ca..73a4c557ee1e1 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js +++ b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js @@ -221,27 +221,7 @@ describe('useMutableSource', () => { const mutableSource = createMutableSource(source, param => param.version); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - () => Scheduler.log('Sync effect'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { , () => Scheduler.log('Sync effect'), ); - } + }); + // Do enough work to read from one component await waitFor(['a:one']); @@ -456,13 +437,9 @@ describe('useMutableSource', () => { // Changing values should schedule an update with React. // Start working on this update but don't finish it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - source.value = 'two'; - }); - } else { + React.startTransition(() => { source.value = 'two'; - } + }); await waitFor(['a:two']); // Re-renders that occur before the update is processed @@ -720,33 +697,7 @@ describe('useMutableSource', () => { // Because the store has not changed yet, there are no pending updates, // so it is considered safe to read from when we start this render. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - , - () => Scheduler.log('Sync effect'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { , () => Scheduler.log('Sync effect'), ); - } + }); + await waitFor(['a:a:one', 'b:b:one']); // Mutating the source should trigger a tear detection on the next read, @@ -856,26 +808,7 @@ describe('useMutableSource', () => { await act(async () => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); + await waitFor(['a:one']); // Mutate source @@ -1524,17 +1458,7 @@ describe('useMutableSource', () => { expect(root).toMatchRenderedOutput('a0'); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render( - <> - - - - , - ); - }); - } else { + React.startTransition(() => { root.render( <> @@ -1542,7 +1466,7 @@ describe('useMutableSource', () => { , ); - } + }); await waitFor(['a0', 'b0']); // Mutate in an event. This schedules a subscription update on a, which @@ -1676,13 +1600,9 @@ describe('useMutableSource', () => { await act(async () => { // Switch the parent and the child to read using the same config - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Start rendering the parent, but yield before rendering the child await waitFor(['Parent: 2']); @@ -1693,21 +1613,7 @@ describe('useMutableSource', () => { source.valueB = '3'; }); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // In default sync mode, all of the updates flush sync. - await waitFor([ - // The partial render completes - 'Child: 2', - 'Commit: 2, 2', - 'Parent: 3', - 'Child: 3', - ]); - - await waitForAll([ - // Now finish the rest of the update - 'Commit: 3, 3', - ]); - } else { + if (gate(flags => flags.forceConcurrentByDefaultForTesting)) { await waitFor([ // The partial render completes 'Child: 2', @@ -1727,6 +1633,20 @@ describe('useMutableSource', () => { 'Child: 3', 'Commit: 3, 3', ]); + } else { + // In default sync mode, all of the updates flush sync. + await waitFor([ + // The partial render completes + 'Child: 2', + 'Commit: 2, 2', + 'Parent: 3', + 'Child: 3', + ]); + + await waitForAll([ + // Now finish the rest of the update + 'Commit: 3, 3', + ]); } }); }); @@ -1843,26 +1763,7 @@ describe('useMutableSource', () => { await act(async () => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); + await waitFor(['a:one']); const PrevScheduler = Scheduler; @@ -1924,26 +1826,7 @@ describe('useMutableSource', () => { await act(async () => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); + await waitFor(['a:one']); const PrevScheduler = Scheduler; diff --git a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js index 87a9d2ea4fb5f..adf98fb4ede9a 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js +++ b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js @@ -260,23 +260,15 @@ describe('useMutableSourceHydration', () => { await expect(async () => { await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactDOMClient.hydrateRoot(container, , { - mutableSources: [mutableSource], - onRecoverableError(error) { - Scheduler.log('Log error: ' + error.message); - }, - }); - }); - } else { + React.startTransition(() => { ReactDOMClient.hydrateRoot(container, , { mutableSources: [mutableSource], onRecoverableError(error) { Scheduler.log('Log error: ' + error.message); }, }); - } + }); + await waitFor(['a:one']); source.value = 'two'; }); diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js index 3e29b28500003..468f62d39a722 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js @@ -95,17 +95,11 @@ describe('ReactTestRendererAsync', () => { } let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create(, { - unstable_isConcurrent: true, - }); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create(, { unstable_isConcurrent: true, }); - } + }); // Flush the first two siblings await waitFor(['A:1', 'B:1']); @@ -141,17 +135,11 @@ describe('ReactTestRendererAsync', () => { } let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create(, { - unstable_isConcurrent: true, - }); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create(, { unstable_isConcurrent: true, }); - } + }); // Flush the some of the changes, but don't commit await waitFor(['A:1']); diff --git a/packages/react/src/__tests__/ReactProfiler-test.internal.js b/packages/react/src/__tests__/ReactProfiler-test.internal.js index d728d002587b7..25386df33abcf 100644 --- a/packages/react/src/__tests__/ReactProfiler-test.internal.js +++ b/packages/react/src/__tests__/ReactProfiler-test.internal.js @@ -206,19 +206,7 @@ describe(`onRender`, () => { return null; }; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - , - { - unstable_isConcurrent: true, - }, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -228,7 +216,7 @@ describe(`onRender`, () => { unstable_isConcurrent: true, }, ); - } + }); // Times are logged until a render is committed. await waitFor(['first']); @@ -758,17 +746,7 @@ describe(`onRender`, () => { Scheduler.unstable_advanceTime(5); // 0 -> 5 // Render partially, but run out of time before completing. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -776,7 +754,8 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); + await waitFor(['Yield:2']); expect(callback).toHaveBeenCalledTimes(0); @@ -805,20 +784,7 @@ describe(`onRender`, () => { // Render partially, but don't finish. // This partial render should take 5ms of simulated time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -829,7 +795,8 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); + await waitFor(['Yield:5']); expect(callback).toHaveBeenCalledTimes(0); @@ -871,17 +838,7 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render should take 10ms of simulated time. let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create( - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create( @@ -889,7 +846,8 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); + await waitFor(['Yield:10']); expect(callback).toHaveBeenCalledTimes(0); @@ -958,17 +916,7 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render should take 3ms of simulated time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update( - - - - - , - ); - }); - } else { + React.startTransition(() => { renderer.update( @@ -976,7 +924,8 @@ describe(`onRender`, () => { , ); - } + }); + await waitFor(['Yield:3']); expect(callback).toHaveBeenCalledTimes(0); @@ -1078,13 +1027,10 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render will take 10ms of actual render time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - first.setState({renderTime: 10}); - }); - } else { + React.startTransition(() => { first.setState({renderTime: 10}); - } + }); + await waitFor(['FirstComponent:10']); expect(callback).toHaveBeenCalledTimes(0); diff --git a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js index 218cd3a2daabb..d28e2ad8de64a 100644 --- a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js +++ b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js @@ -161,13 +161,9 @@ describe('ReactProfiler DevTools integration', () => { // for updates. Scheduler.unstable_advanceTime(10000); // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update(); - }); - } else { + React.startTransition(() => { root.update(); - } + }); // Update B should not instantly expire. await waitFor([]); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 791ed622a0ff6..7cb339c83cc85 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -145,12 +145,11 @@ export const disableLegacyContext = false; export const enableUseRefAccessWarning = false; // Enables time slicing for updates that aren't wrapped in startTransition. -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = __EXPERIMENTAL__; -// Adds an opt-in to time slicing for updates that aren't wrapped in -// startTransition. Only relevant when enableSyncDefaultUpdates is disabled. +// Adds an opt-in to time slicing for updates that aren't wrapped in startTransition. export const allowConcurrentByDefault = false; // ----------------------------------------------------------------------------- diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 239228901600d..e96ce86b00286 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -66,7 +66,7 @@ export const createRootStrictEffectsByDefault = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = true; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 326f7d5385b46..97556a05514ce 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -53,7 +53,7 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index bbc988448c543..6437b4de07086 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -53,7 +53,7 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = __EXPERIMENTAL__; export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 751695f8eb0b1..55535ce5e464d 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -52,7 +52,7 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 31d2292dcf4e8..1df2ff6b9eeea 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -53,7 +53,7 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 827d1413b5949..58cfcdfff4214 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -20,7 +20,7 @@ export const enableUseRefAccessWarning = __VARIANT__; export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; export const enableLazyContextPropagation = __VARIANT__; -export const enableSyncDefaultUpdates = __VARIANT__; +export const forceConcurrentByDefaultForTesting = __VARIANT__; export const enableUnifiedSyncLane = __VARIANT__; export const enableTransitionTracing = __VARIANT__; export const enableCustomElementPropertySupport = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 88951390b16ab..426a9ec8013e6 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -105,7 +105,7 @@ export const enableUseMutableSource = true; export const useModernStrictMode = false; export const enableFizzExternalRuntime = true; -export const enableSyncDefaultUpdates = true; +export const forceConcurrentByDefaultForTesting = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/packages/use-subscription/src/__tests__/useSubscription-test.js b/packages/use-subscription/src/__tests__/useSubscription-test.js index f3d8d3905320a..19eba0a15be8e 100644 --- a/packages/use-subscription/src/__tests__/useSubscription-test.js +++ b/packages/use-subscription/src/__tests__/useSubscription-test.js @@ -339,13 +339,9 @@ describe('useSubscription', () => { // Start React update, but don't finish await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update(); - }); - } else { + React.startTransition(() => { renderer.update(); - } + }); await waitFor(['Child: b-0']); expect(log).toEqual(['Parent.componentDidMount']); @@ -447,13 +443,9 @@ describe('useSubscription', () => { // Start React update, but don't finish await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update(); - }); - } else { + React.startTransition(() => { renderer.update(); - } + }); await waitFor(['Child: b-0']); expect(log).toEqual([]); @@ -632,21 +624,13 @@ describe('useSubscription', () => { // Interrupt with a second mutation "C" -> "D". // This update will not be eagerly evaluated, // but useSubscription() should eagerly close over the updated value to avoid tearing. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - mutate('C'); - }); - } else { + React.startTransition(() => { mutate('C'); - } + }); await waitFor(['render:first:C', 'render:second:C']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - mutate('D'); - }); - } else { + React.startTransition(() => { mutate('D'); - } + }); await waitForAll(['render:first:D', 'render:second:D']); // No more pending updates diff --git a/scripts/jest/setupTests.www.js b/scripts/jest/setupTests.www.js index a51b5838ee439..2fc6da49d55ed 100644 --- a/scripts/jest/setupTests.www.js +++ b/scripts/jest/setupTests.www.js @@ -9,7 +9,7 @@ jest.mock('shared/ReactFeatureFlags', () => { const actual = jest.requireActual('shared/forks/ReactFeatureFlags.www'); // This flag is only used by tests, it should never be set elsewhere. - actual.enableSyncDefaultUpdates = __VARIANT__; + actual.forceConcurrentByDefaultForTesting = !__VARIANT__; return actual; });