JSTQL-JS-Transform/output_testing/422ReactDOMUpdateBatching.js

54 lines
No EOL
2.2 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { needsStateRestore, restoreStateIfNeeded } from './ReactDOMControlledComponent';
import { batchedUpdates as batchedUpdatesImpl, discreteUpdates as discreteUpdatesImpl, flushSyncWork } from 'react-reconciler/src/ReactFiberReconciler';
// Used as a way to call batchedUpdates when we don't have a reference to
// the renderer. Such as when we're dispatching events or if third party
// libraries need to call batchedUpdates. Eventually, this API will go away when
// everything is batched by default. We'll then have a similar API to opt-out of
// scheduled work and instead do synchronous work.
let isInsideEventHandler = false;
function finishEventHandler() {
// Here we wait until all updates have propagated, which is important
// when using controlled components within layers:
// https://github.com/facebook/react/issues/1698
// Then we restore state of any controlled component.
const controlledComponentsHavePendingUpdates = needsStateRestore();
if (controlledComponentsHavePendingUpdates) {
// If a controlled event was fired, we may need to restore the state of
// the DOM node back to the controlled value. This is necessary when React
// 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.
// @TODO Should move to flushSyncWork once legacy mode is removed but since this flushSync
// flushes passive effects we can't do this yet.
flushSyncWork();
restoreStateIfNeeded();
}
}
export function batchedUpdates(fn, a, b) {
if (isInsideEventHandler) {
// If we are currently inside another batch, we need to wait until it
// fully completes before restoring state.
return a |> fn(%, b);
}
isInsideEventHandler = true;
try {
return batchedUpdatesImpl(fn, a, b);
} finally {
isInsideEventHandler = false;
finishEventHandler();
}
}
// TODO: Replace with flushSync
export function discreteUpdates(fn, a, b, c, d) {
return discreteUpdatesImpl(fn, a, b, c, d);
}