From 67e8bc8b26b28b63162b4f4844f26153b82de607 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 30 Jun 2021 17:19:37 -0400 Subject: [PATCH 1/2] Replace flushDiscreteUpdates with flushSync flushDiscreteUpdates is almost the same as flushSync. It forces passive effects to fire, because of an outdated heuristic, which isn't ideal but not that important. Besides that, the only remaining difference between flushDiscreteUpdates and flushSync is that flushDiscreteUpdates does not warn if you call it from inside an effect/lifecycle. This is because it might get triggered by a nested event dispatch, like `el.focus()`. So I added a new method, flushSyncWithWarningIfAlreadyRendering, which is used for the public flushSync API. It includes the warning. And I removed the warning from flushSync, so the event system can call that one. In production, flushSyncWithWarningIfAlreadyRendering gets inlined to flushSync, so the behavior is identical. Another way of thinking about this PR is that I renamed flushSync to flushSyncWithWarningIfAlreadyRendering and flushDiscreteUpdates to flushSync (and fixed the passive effects thing). The point is to prevent these from subtly diverging in the future. --- .../src/__tests__/ReactDOMFiber-test.js | 8 +-- packages/react-dom/src/client/ReactDOM.js | 10 ++-- .../src/events/ReactDOMUpdateBatching.js | 8 +-- packages/react-noop-renderer/src/ReactNoop.js | 1 - .../src/createReactNoop.js | 4 +- .../src/ReactFiberReconciler.js | 10 ++-- .../src/ReactFiberReconciler.new.js | 4 +- .../src/ReactFiberReconciler.old.js | 4 +- .../src/ReactFiberWorkLoop.new.js | 52 ++++++------------- .../src/ReactFiberWorkLoop.old.js | 52 ++++++------------- .../src/__tests__/ReactFlushSync-test.js | 23 ++++++++ .../src/ReactTestRenderer.js | 4 +- 12 files changed, 75 insertions(+), 105 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js index 36c8367af5d48..ff1ea1771fc87 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js @@ -1154,19 +1154,13 @@ describe('ReactDOMFiber', () => { expect(ops).toEqual(['A']); if (__DEV__) { - const errorCalls = console.error.calls.count(); + expect(console.error.calls.count()).toBe(2); expect(console.error.calls.argsFor(0)[0]).toMatch( 'ReactDOM.render is no longer supported in React 18', ); expect(console.error.calls.argsFor(1)[0]).toMatch( 'ReactDOM.render is no longer supported in React 18', ); - // TODO: this warning shouldn't be firing in the first place if user didn't call it. - for (let i = 2; i < errorCalls; i++) { - expect(console.error.calls.argsFor(i)[0]).toMatch( - 'unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.', - ); - } } }); diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 8e974697075f1..af1385e6fe349 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -23,8 +23,8 @@ import {createEventHandle} from './ReactDOMEventHandle'; import { batchedUpdates, discreteUpdates, - flushDiscreteUpdates, flushSync, + flushSyncWithWarningIfAlreadyRendering, flushControlled, injectIntoDevTools, attemptSynchronousHydration, @@ -97,11 +97,7 @@ if (__DEV__) { } setRestoreImplementation(restoreControlledState); -setBatchingImplementation( - batchedUpdates, - discreteUpdates, - flushDiscreteUpdates, -); +setBatchingImplementation(batchedUpdates, discreteUpdates, flushSync); function createPortal( children: ReactNodeList, @@ -166,7 +162,7 @@ const Internals = { export { createPortal, batchedUpdates as unstable_batchedUpdates, - flushSync, + flushSyncWithWarningIfAlreadyRendering as flushSync, Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ReactVersion as version, // Disabled behind disableLegacyReactDOMAPIs diff --git a/packages/react-dom/src/events/ReactDOMUpdateBatching.js b/packages/react-dom/src/events/ReactDOMUpdateBatching.js index f2fbfe4c3f329..d3c46630b148e 100644 --- a/packages/react-dom/src/events/ReactDOMUpdateBatching.js +++ b/packages/react-dom/src/events/ReactDOMUpdateBatching.js @@ -23,7 +23,7 @@ let batchedUpdatesImpl = function(fn, bookkeeping) { let discreteUpdatesImpl = function(fn, a, b, c, d) { return fn(a, b, c, d); }; -let flushDiscreteUpdatesImpl = function() {}; +let flushSyncImpl = function() {}; let isInsideEventHandler = false; @@ -39,7 +39,7 @@ function finishEventHandler() { // bails out of the update without touching the DOM. // TODO: Restore state in the microtask, after the discrete updates flush, // instead of early flushing them here. - flushDiscreteUpdatesImpl(); + flushSyncImpl(); restoreStateIfNeeded(); } } @@ -67,9 +67,9 @@ export function discreteUpdates(fn, a, b, c, d) { export function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, - _flushDiscreteUpdatesImpl, + _flushSyncImpl, ) { batchedUpdatesImpl = _batchedUpdatesImpl; discreteUpdatesImpl = _discreteUpdatesImpl; - flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + flushSyncImpl = _flushSyncImpl; } diff --git a/packages/react-noop-renderer/src/ReactNoop.js b/packages/react-noop-renderer/src/ReactNoop.js index c09fa2d8000f5..5e5567f9e0947 100644 --- a/packages/react-noop-renderer/src/ReactNoop.js +++ b/packages/react-noop-renderer/src/ReactNoop.js @@ -41,7 +41,6 @@ export const { unbatchedUpdates, discreteUpdates, idleUpdates, - flushDiscreteUpdates, flushSync, flushPassiveEffects, act, diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 8dbadafd2c22a..a5a5ac9659921 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -915,10 +915,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { } }, - flushDiscreteUpdates: NoopRenderer.flushDiscreteUpdates, - flushSync(fn: () => mixed) { - NoopRenderer.flushSync(fn); + NoopRenderer.flushSyncWithWarningIfAlreadyRendering(fn); }, flushPassiveEffects: NoopRenderer.flushPassiveEffects, diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index bc169fd8a6475..1275736c157f8 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -21,9 +21,9 @@ import { unbatchedUpdates as unbatchedUpdates_old, deferredUpdates as deferredUpdates_old, discreteUpdates as discreteUpdates_old, - flushDiscreteUpdates as flushDiscreteUpdates_old, flushControlled as flushControlled_old, flushSync as flushSync_old, + flushSyncWithWarningIfAlreadyRendering as flushSyncWithWarningIfAlreadyRendering_old, flushPassiveEffects as flushPassiveEffects_old, getPublicRootInstance as getPublicRootInstance_old, attemptSynchronousHydration as attemptSynchronousHydration_old, @@ -59,9 +59,9 @@ import { unbatchedUpdates as unbatchedUpdates_new, deferredUpdates as deferredUpdates_new, discreteUpdates as discreteUpdates_new, - flushDiscreteUpdates as flushDiscreteUpdates_new, flushControlled as flushControlled_new, flushSync as flushSync_new, + flushSyncWithWarningIfAlreadyRendering as flushSyncWithWarningIfAlreadyRendering_new, flushPassiveEffects as flushPassiveEffects_new, getPublicRootInstance as getPublicRootInstance_new, attemptSynchronousHydration as attemptSynchronousHydration_new, @@ -108,13 +108,13 @@ export const deferredUpdates = enableNewReconciler export const discreteUpdates = enableNewReconciler ? discreteUpdates_new : discreteUpdates_old; -export const flushDiscreteUpdates = enableNewReconciler - ? flushDiscreteUpdates_new - : flushDiscreteUpdates_old; export const flushControlled = enableNewReconciler ? flushControlled_new : flushControlled_old; export const flushSync = enableNewReconciler ? flushSync_new : flushSync_old; +export const flushSyncWithWarningIfAlreadyRendering = enableNewReconciler + ? flushSyncWithWarningIfAlreadyRendering_new + : flushSyncWithWarningIfAlreadyRendering_old; export const flushPassiveEffects = enableNewReconciler ? flushPassiveEffects_new : flushPassiveEffects_old; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.new.js b/packages/react-reconciler/src/ReactFiberReconciler.new.js index f406f8592b0d1..15520dbc4ec78 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.new.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.new.js @@ -57,7 +57,7 @@ import { flushControlled, deferredUpdates, discreteUpdates, - flushDiscreteUpdates, + flushSyncWithWarningIfAlreadyRendering, flushPassiveEffects, } from './ReactFiberWorkLoop.new'; import { @@ -330,9 +330,9 @@ export { unbatchedUpdates, deferredUpdates, discreteUpdates, - flushDiscreteUpdates, flushControlled, flushSync, + flushSyncWithWarningIfAlreadyRendering, flushPassiveEffects, }; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.old.js b/packages/react-reconciler/src/ReactFiberReconciler.old.js index f6ae425b4400b..556d2f41ed640 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.old.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.old.js @@ -57,7 +57,7 @@ import { flushControlled, deferredUpdates, discreteUpdates, - flushDiscreteUpdates, + flushSyncWithWarningIfAlreadyRendering, flushPassiveEffects, } from './ReactFiberWorkLoop.old'; import { @@ -330,9 +330,9 @@ export { unbatchedUpdates, deferredUpdates, discreteUpdates, - flushDiscreteUpdates, flushControlled, flushSync, + flushSyncWithWarningIfAlreadyRendering, flushPassiveEffects, }; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 7f429c873438a..c2cc90f0bef98 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -1044,34 +1044,6 @@ export function getExecutionContext(): ExecutionContext { return executionContext; } -export function flushDiscreteUpdates() { - // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. - // However, `act` uses `batchedUpdates`, so there's no way to distinguish - // those two cases. Need to fix this before exposing flushDiscreteUpdates - // as a public API. - if ( - (executionContext & (BatchedContext | RenderContext | CommitContext)) !== - NoContext - ) { - if (__DEV__) { - if ((executionContext & RenderContext) !== NoContext) { - console.error( - 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + - 'already rendering.', - ); - } - } - // We're already rendering, so we can't synchronously flush pending work. - // This is probably a nested event dispatch triggered by a lifecycle/effect, - // like `el.focus()`. Exit. - return; - } - flushSyncCallbacks(); - // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. - flushPassiveEffects(); -} - export function deferredUpdates(fn: () => A): A { const previousPriority = getCurrentUpdatePriority(); const prevTransition = ReactCurrentBatchConfig.transition; @@ -1165,18 +1137,26 @@ export function flushSync(fn: A => R, a: A): R { // the stack. if ((executionContext & (RenderContext | CommitContext)) === NoContext) { flushSyncCallbacks(); - } else { - if (__DEV__) { - console.error( - 'flushSync was called from inside a lifecycle method. React cannot ' + - 'flush when React is already rendering. Consider moving this call to ' + - 'a scheduler task or micro task.', - ); - } } } } +export function flushSyncWithWarningIfAlreadyRendering( + fn: A => R, + a: A, +): R { + if (__DEV__) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + console.error( + 'flushSync was called from inside a lifecycle method. React cannot ' + + 'flush when React is already rendering. Consider moving this call to ' + + 'a scheduler task or micro task.', + ); + } + } + return flushSync(fn, a); +} + export function flushControlled(fn: () => mixed): void { const prevExecutionContext = executionContext; executionContext |= BatchedContext; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index f356fc3f1156a..f2996dfd0d0f8 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -1044,34 +1044,6 @@ export function getExecutionContext(): ExecutionContext { return executionContext; } -export function flushDiscreteUpdates() { - // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. - // However, `act` uses `batchedUpdates`, so there's no way to distinguish - // those two cases. Need to fix this before exposing flushDiscreteUpdates - // as a public API. - if ( - (executionContext & (BatchedContext | RenderContext | CommitContext)) !== - NoContext - ) { - if (__DEV__) { - if ((executionContext & RenderContext) !== NoContext) { - console.error( - 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + - 'already rendering.', - ); - } - } - // We're already rendering, so we can't synchronously flush pending work. - // This is probably a nested event dispatch triggered by a lifecycle/effect, - // like `el.focus()`. Exit. - return; - } - flushSyncCallbacks(); - // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. - flushPassiveEffects(); -} - export function deferredUpdates(fn: () => A): A { const previousPriority = getCurrentUpdatePriority(); const prevTransition = ReactCurrentBatchConfig.transition; @@ -1165,18 +1137,26 @@ export function flushSync(fn: A => R, a: A): R { // the stack. if ((executionContext & (RenderContext | CommitContext)) === NoContext) { flushSyncCallbacks(); - } else { - if (__DEV__) { - console.error( - 'flushSync was called from inside a lifecycle method. React cannot ' + - 'flush when React is already rendering. Consider moving this call to ' + - 'a scheduler task or micro task.', - ); - } } } } +export function flushSyncWithWarningIfAlreadyRendering( + fn: A => R, + a: A, +): R { + if (__DEV__) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { + console.error( + 'flushSync was called from inside a lifecycle method. React cannot ' + + 'flush when React is already rendering. Consider moving this call to ' + + 'a scheduler task or micro task.', + ); + } + } + return flushSync(fn, a); +} + export function flushControlled(fn: () => mixed): void { const prevExecutionContext = executionContext; executionContext |= BatchedContext; diff --git a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js index a3a74d739a9a3..c73e46ddc5e31 100644 --- a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js +++ b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js @@ -173,4 +173,27 @@ describe('ReactFlushSync', () => { // Effect flushes after paint. expect(Scheduler).toHaveYielded(['Effect']); }); + + test('does not flush pending passive effects', async () => { + function App() { + useEffect(() => { + Scheduler.unstable_yieldValue('Effect'); + }, []); + return ; + } + + const root = ReactNoop.createRoot(); + await act(async () => { + root.render(); + expect(Scheduler).toFlushUntilNextPaint(['Child']); + expect(root).toMatchRenderedOutput('Child'); + + // Passive effects are pending. Calling flushSync should not affect them. + ReactNoop.flushSync(); + // Effects still haven't fired. + expect(Scheduler).toHaveYielded([]); + }); + // Now the effects have fired. + expect(Scheduler).toHaveYielded(['Effect']); + }); }); diff --git a/packages/react-test-renderer/src/ReactTestRenderer.js b/packages/react-test-renderer/src/ReactTestRenderer.js index eb00975506956..671d601c48b01 100644 --- a/packages/react-test-renderer/src/ReactTestRenderer.js +++ b/packages/react-test-renderer/src/ReactTestRenderer.js @@ -18,7 +18,7 @@ import { getPublicRootInstance, createContainer, updateContainer, - flushSync, + flushSyncWithWarningIfAlreadyRendering, injectIntoDevTools, batchedUpdates, } from 'react-reconciler/src/ReactFiberReconciler'; @@ -543,7 +543,7 @@ function create(element: React$Element, options: TestRendererOptions) { }, unstable_flushSync(fn: () => T): T { - return flushSync(fn); + return flushSyncWithWarningIfAlreadyRendering(fn); }, }; From 464ee053951a6130055d8d649e2217d422c85a26 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 30 Jun 2021 18:06:52 -0400 Subject: [PATCH 2/2] Invert so the one with the warning is the default one To make Seb happy --- packages/react-dom/src/client/ReactDOM.js | 10 +++++++--- packages/react-noop-renderer/src/createReactNoop.js | 2 +- .../react-reconciler/src/ReactFiberReconciler.js | 10 +++++----- .../react-reconciler/src/ReactFiberReconciler.new.js | 4 ++-- .../react-reconciler/src/ReactFiberReconciler.old.js | 4 ++-- .../react-reconciler/src/ReactFiberWorkLoop.new.js | 12 ++++++------ .../react-reconciler/src/ReactFiberWorkLoop.old.js | 12 ++++++------ .../react-test-renderer/src/ReactTestRenderer.js | 4 ++-- 8 files changed, 31 insertions(+), 27 deletions(-) diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index af1385e6fe349..80fc3d1e4a05e 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -24,7 +24,7 @@ import { batchedUpdates, discreteUpdates, flushSync, - flushSyncWithWarningIfAlreadyRendering, + flushSyncWithoutWarningIfAlreadyRendering, flushControlled, injectIntoDevTools, attemptSynchronousHydration, @@ -97,7 +97,11 @@ if (__DEV__) { } setRestoreImplementation(restoreControlledState); -setBatchingImplementation(batchedUpdates, discreteUpdates, flushSync); +setBatchingImplementation( + batchedUpdates, + discreteUpdates, + flushSyncWithoutWarningIfAlreadyRendering, +); function createPortal( children: ReactNodeList, @@ -162,7 +166,7 @@ const Internals = { export { createPortal, batchedUpdates as unstable_batchedUpdates, - flushSyncWithWarningIfAlreadyRendering as flushSync, + flushSync, Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ReactVersion as version, // Disabled behind disableLegacyReactDOMAPIs diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index a5a5ac9659921..eb7e74193341c 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -916,7 +916,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { }, flushSync(fn: () => mixed) { - NoopRenderer.flushSyncWithWarningIfAlreadyRendering(fn); + NoopRenderer.flushSync(fn); }, flushPassiveEffects: NoopRenderer.flushPassiveEffects, diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 1275736c157f8..bf78e9e41c390 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -23,7 +23,7 @@ import { discreteUpdates as discreteUpdates_old, flushControlled as flushControlled_old, flushSync as flushSync_old, - flushSyncWithWarningIfAlreadyRendering as flushSyncWithWarningIfAlreadyRendering_old, + flushSyncWithoutWarningIfAlreadyRendering as flushSyncWithoutWarningIfAlreadyRendering_old, flushPassiveEffects as flushPassiveEffects_old, getPublicRootInstance as getPublicRootInstance_old, attemptSynchronousHydration as attemptSynchronousHydration_old, @@ -61,7 +61,7 @@ import { discreteUpdates as discreteUpdates_new, flushControlled as flushControlled_new, flushSync as flushSync_new, - flushSyncWithWarningIfAlreadyRendering as flushSyncWithWarningIfAlreadyRendering_new, + flushSyncWithoutWarningIfAlreadyRendering as flushSyncWithoutWarningIfAlreadyRendering_new, flushPassiveEffects as flushPassiveEffects_new, getPublicRootInstance as getPublicRootInstance_new, attemptSynchronousHydration as attemptSynchronousHydration_new, @@ -112,9 +112,9 @@ export const flushControlled = enableNewReconciler ? flushControlled_new : flushControlled_old; export const flushSync = enableNewReconciler ? flushSync_new : flushSync_old; -export const flushSyncWithWarningIfAlreadyRendering = enableNewReconciler - ? flushSyncWithWarningIfAlreadyRendering_new - : flushSyncWithWarningIfAlreadyRendering_old; +export const flushSyncWithoutWarningIfAlreadyRendering = enableNewReconciler + ? flushSyncWithoutWarningIfAlreadyRendering_new + : flushSyncWithoutWarningIfAlreadyRendering_old; export const flushPassiveEffects = enableNewReconciler ? flushPassiveEffects_new : flushPassiveEffects_old; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.new.js b/packages/react-reconciler/src/ReactFiberReconciler.new.js index 15520dbc4ec78..c8b61182d5737 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.new.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.new.js @@ -57,7 +57,7 @@ import { flushControlled, deferredUpdates, discreteUpdates, - flushSyncWithWarningIfAlreadyRendering, + flushSyncWithoutWarningIfAlreadyRendering, flushPassiveEffects, } from './ReactFiberWorkLoop.new'; import { @@ -332,7 +332,7 @@ export { discreteUpdates, flushControlled, flushSync, - flushSyncWithWarningIfAlreadyRendering, + flushSyncWithoutWarningIfAlreadyRendering, flushPassiveEffects, }; diff --git a/packages/react-reconciler/src/ReactFiberReconciler.old.js b/packages/react-reconciler/src/ReactFiberReconciler.old.js index 556d2f41ed640..7e74bf6a1feea 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.old.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.old.js @@ -57,7 +57,7 @@ import { flushControlled, deferredUpdates, discreteUpdates, - flushSyncWithWarningIfAlreadyRendering, + flushSyncWithoutWarningIfAlreadyRendering, flushPassiveEffects, } from './ReactFiberWorkLoop.old'; import { @@ -332,7 +332,7 @@ export { discreteUpdates, flushControlled, flushSync, - flushSyncWithWarningIfAlreadyRendering, + flushSyncWithoutWarningIfAlreadyRendering, flushPassiveEffects, }; diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index c2cc90f0bef98..c8e13fa3a5eb2 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -1114,7 +1114,10 @@ export function unbatchedUpdates(fn: (a: A) => R, a: A): R { } } -export function flushSync(fn: A => R, a: A): R { +export function flushSyncWithoutWarningIfAlreadyRendering( + fn: A => R, + a: A, +): R { const prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -1141,10 +1144,7 @@ export function flushSync(fn: A => R, a: A): R { } } -export function flushSyncWithWarningIfAlreadyRendering( - fn: A => R, - a: A, -): R { +export function flushSync(fn: A => R, a: A): R { if (__DEV__) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { console.error( @@ -1154,7 +1154,7 @@ export function flushSyncWithWarningIfAlreadyRendering( ); } } - return flushSync(fn, a); + return flushSyncWithoutWarningIfAlreadyRendering(fn, a); } export function flushControlled(fn: () => mixed): void { diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index f2996dfd0d0f8..c4f51481eaf98 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -1114,7 +1114,10 @@ export function unbatchedUpdates(fn: (a: A) => R, a: A): R { } } -export function flushSync(fn: A => R, a: A): R { +export function flushSyncWithoutWarningIfAlreadyRendering( + fn: A => R, + a: A, +): R { const prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -1141,10 +1144,7 @@ export function flushSync(fn: A => R, a: A): R { } } -export function flushSyncWithWarningIfAlreadyRendering( - fn: A => R, - a: A, -): R { +export function flushSync(fn: A => R, a: A): R { if (__DEV__) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { console.error( @@ -1154,7 +1154,7 @@ export function flushSyncWithWarningIfAlreadyRendering( ); } } - return flushSync(fn, a); + return flushSyncWithoutWarningIfAlreadyRendering(fn, a); } export function flushControlled(fn: () => mixed): void { diff --git a/packages/react-test-renderer/src/ReactTestRenderer.js b/packages/react-test-renderer/src/ReactTestRenderer.js index 671d601c48b01..eb00975506956 100644 --- a/packages/react-test-renderer/src/ReactTestRenderer.js +++ b/packages/react-test-renderer/src/ReactTestRenderer.js @@ -18,7 +18,7 @@ import { getPublicRootInstance, createContainer, updateContainer, - flushSyncWithWarningIfAlreadyRendering, + flushSync, injectIntoDevTools, batchedUpdates, } from 'react-reconciler/src/ReactFiberReconciler'; @@ -543,7 +543,7 @@ function create(element: React$Element, options: TestRendererOptions) { }, unstable_flushSync(fn: () => T): T { - return flushSyncWithWarningIfAlreadyRendering(fn); + return flushSync(fn); }, };