Skip to content

Commit b1a0af9

Browse files
committed
[DOM] move flushSync out of the reconciler (#28500)
This PR moves `flushSync` out of the reconciler. there is still an internal implementation that is used when these semantics are needed for React methods such as `unmount` on roots. This new isomorphic `flushSync` is only used in builds that no longer support legacy mode. Additionally all the internal uses of flushSync in the reconciler have been replaced with more direct methods. There is a new `updateContainerSync` method which updates a container but forces it to the Sync lane and flushes passive effects if necessary. This combined with flushSyncWork can be used to replace flushSync for all instances of internal usage. We still maintain the original flushSync implementation as `flushSyncFromReconciler` because it will be used as the flushSync implementation for FB builds. This is because it has special legacy mode handling that the new isomorphic implementation does not need to consider. It will be removed from production OSS builds by closure though DiffTrain build for [4c12339](4c12339)
1 parent ffde2c0 commit b1a0af9

25 files changed

+79363
-79172
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8e1462e8c471fbec98aac2b3e1326498d0ff7139
1+
4c12339ce3fa398050d1026c616ea43d43dcaf4a

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 72 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if (__DEV__) {
6666
return self;
6767
}
6868

69-
var ReactVersion = "19.0.0-www-classic-6d726b4b";
69+
var ReactVersion = "19.0.0-www-classic-52633ec3";
7070

7171
var LegacyRoot = 0;
7272
var ConcurrentRoot = 1;
@@ -25563,17 +25563,14 @@ if (__DEV__) {
2556325563
}
2556425564

2556525565
var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map;
25566-
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
25567-
ReactCurrentCache = ReactSharedInternals.ReactCurrentCache,
25568-
ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner,
25569-
ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig,
25570-
ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
25566+
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
25567+
var ReactCurrentCache = ReactSharedInternals.ReactCurrentCache;
25568+
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
25569+
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
25570+
var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
2557125571
var NoContext =
2557225572
/* */
2557325573
0;
25574-
var BatchedContext =
25575-
/* */
25576-
1;
2557725574
var RenderContext =
2557825575
/* */
2557925576
2;
@@ -25869,13 +25866,11 @@ if (__DEV__) {
2586925866

2587025867
if (transition !== null) {
2587125868
{
25872-
var batchConfigTransition = ReactCurrentBatchConfig.transition;
25873-
25874-
if (!batchConfigTransition._updatedFibers) {
25875-
batchConfigTransition._updatedFibers = new Set();
25869+
if (!transition._updatedFibers) {
25870+
transition._updatedFibers = new Set();
2587625871
}
2587725872

25878-
batchConfigTransition._updatedFibers.add(fiber);
25873+
transition._updatedFibers.add(fiber);
2587925874
}
2588025875

2588125876
var actionScopeLane = peekEntangledActionLane();
@@ -26002,7 +25997,8 @@ if (__DEV__) {
2600225997
if (transition !== null && transition.name != null) {
2600325998
if (transition.startTime === -1) {
2600425999
transition.startTime = now$1();
26005-
}
26000+
} // $FlowFixMe[prop-missing]: The BatchConfigTransition and Transition types are incompatible but was previously untyped and thus uncaught
26001+
// $FlowFixMe[incompatible-call]: "
2600626002

2600726003
addTransitionToLanesMap(root, transition, lane);
2600826004
}
@@ -26597,51 +26593,15 @@ if (__DEV__) {
2659726593
function getExecutionContext() {
2659826594
return executionContext;
2659926595
}
26600-
// Warning, this opts-out of checking the function body.
26601-
// eslint-disable-next-line no-unused-vars
26602-
// eslint-disable-next-line no-redeclare
26603-
// eslint-disable-next-line no-redeclare
26596+
// Returns whether the the call was during a render or not
2660426597

26605-
function flushSync(fn) {
26606-
// In legacy mode, we flush pending passive effects at the beginning of the
26607-
// next event, not at the end of the previous one.
26608-
if (
26609-
rootWithPendingPassiveEffects !== null &&
26610-
!disableLegacyMode &&
26611-
rootWithPendingPassiveEffects.tag === LegacyRoot &&
26612-
(executionContext & (RenderContext | CommitContext)) === NoContext
26613-
) {
26614-
flushPassiveEffects();
26598+
function flushSyncWork() {
26599+
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26600+
flushSyncWorkOnAllRoots();
26601+
return false;
2661526602
}
2661626603

26617-
var prevExecutionContext = executionContext;
26618-
executionContext |= BatchedContext;
26619-
var prevTransition = ReactCurrentBatchConfig.transition;
26620-
var previousPriority = getCurrentUpdatePriority();
26621-
26622-
try {
26623-
setCurrentUpdatePriority(DiscreteEventPriority);
26624-
ReactCurrentBatchConfig.transition = null;
26625-
26626-
if (fn) {
26627-
return fn();
26628-
} else {
26629-
return undefined;
26630-
}
26631-
} finally {
26632-
setCurrentUpdatePriority(previousPriority);
26633-
ReactCurrentBatchConfig.transition = prevTransition;
26634-
executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
26635-
// Note that this will happen even if batchedUpdates is higher up
26636-
// the stack.
26637-
26638-
if (
26639-
(executionContext & (RenderContext | CommitContext)) ===
26640-
NoContext
26641-
) {
26642-
flushSyncWorkOnAllRoots();
26643-
}
26644-
}
26604+
return true;
2664526605
}
2664626606
function isInvalidExecutionContextForEventFunction() {
2664726607
// Used to throw if certain APIs are called from the wrong context.
@@ -29250,13 +29210,12 @@ if (__DEV__) {
2925029210
var staleFamilies = update.staleFamilies,
2925129211
updatedFamilies = update.updatedFamilies;
2925229212
flushPassiveEffects();
29253-
flushSync(function () {
29254-
scheduleFibersWithFamiliesRecursively(
29255-
root.current,
29256-
updatedFamilies,
29257-
staleFamilies
29258-
);
29259-
});
29213+
scheduleFibersWithFamiliesRecursively(
29214+
root.current,
29215+
updatedFamilies,
29216+
staleFamilies
29217+
);
29218+
flushSyncWork();
2926029219
}
2926129220
};
2926229221
var scheduleRoot = function (root, element) {
@@ -29268,10 +29227,8 @@ if (__DEV__) {
2926829227
return;
2926929228
}
2927029229

29271-
flushPassiveEffects();
29272-
flushSync(function () {
29273-
updateContainer(element, root, null, null);
29274-
});
29230+
updateContainerSync(element, root, null, null);
29231+
flushSyncWork();
2927529232
}
2927629233
};
2927729234

@@ -30397,14 +30354,40 @@ if (__DEV__) {
3039730354
null
3039830355
);
3039930356
}
30400-
function updateContainer(element, container, parentComponent, callback) {
30357+
function updateContainerSync(
30358+
element,
30359+
container,
30360+
parentComponent,
30361+
callback
30362+
) {
30363+
if (container.tag === LegacyRoot) {
30364+
flushPassiveEffects();
30365+
}
30366+
30367+
var current = container.current;
30368+
updateContainerImpl(
30369+
current,
30370+
SyncLane,
30371+
element,
30372+
container,
30373+
parentComponent,
30374+
callback
30375+
);
30376+
return SyncLane;
30377+
}
30378+
30379+
function updateContainerImpl(
30380+
rootFiber,
30381+
lane,
30382+
element,
30383+
container,
30384+
parentComponent,
30385+
callback
30386+
) {
3040130387
{
3040230388
onScheduleRoot(container, element);
3040330389
}
3040430390

30405-
var current$1 = container.current;
30406-
var lane = requestUpdateLane(current$1);
30407-
3040830391
if (enableSchedulingProfiler) {
3040930392
markRenderScheduled(lane);
3041030393
}
@@ -30453,14 +30436,12 @@ if (__DEV__) {
3045330436
update.callback = callback;
3045430437
}
3045530438

30456-
var root = enqueueUpdate(current$1, update, lane);
30439+
var root = enqueueUpdate(rootFiber, update, lane);
3045730440

3045830441
if (root !== null) {
30459-
scheduleUpdateOnFiber(root, current$1, lane);
30460-
entangleTransitions(root, current$1, lane);
30442+
scheduleUpdateOnFiber(root, rootFiber, lane);
30443+
entangleTransitions(root, rootFiber, lane);
3046130444
}
30462-
30463-
return lane;
3046430445
}
3046530446

3046630447
var shouldErrorImpl = function (fiber) {
@@ -30827,8 +30808,6 @@ if (__DEV__) {
3082730808
var _proto4 = Surface.prototype;
3082830809

3082930810
_proto4.componentDidMount = function componentDidMount() {
30830-
var _this = this;
30831-
3083230811
var _this$props = this.props,
3083330812
height = _this$props.height,
3083430813
width = _this$props.width;
@@ -30843,17 +30822,14 @@ if (__DEV__) {
3084330822
); // We synchronously flush updates coming from above so that they commit together
3084430823
// and so that refs resolve before the parent life cycles.
3084530824

30846-
flushSync(function () {
30847-
updateContainer(_this.props.children, _this._mountNode, _this);
30848-
});
30825+
updateContainerSync(this.props.children, this._mountNode, this);
30826+
flushSyncWork();
3084930827
};
3085030828

3085130829
_proto4.componentDidUpdate = function componentDidUpdate(
3085230830
prevProps,
3085330831
prevState
3085430832
) {
30855-
var _this2 = this;
30856-
3085730833
var props = this.props;
3085830834

3085930835
if (
@@ -30864,27 +30840,23 @@ if (__DEV__) {
3086430840
} // We synchronously flush updates coming from above so that they commit together
3086530841
// and so that refs resolve before the parent life cycles.
3086630842

30867-
flushSync(function () {
30868-
updateContainer(_this2.props.children, _this2._mountNode, _this2);
30869-
});
30843+
updateContainerSync(this.props.children, this._mountNode, this);
30844+
flushSyncWork();
3087030845

3087130846
if (this._surface.render) {
3087230847
this._surface.render();
3087330848
}
3087430849
};
3087530850

3087630851
_proto4.componentWillUnmount = function componentWillUnmount() {
30877-
var _this3 = this;
30878-
3087930852
// We synchronously flush updates coming from above so that they commit together
3088030853
// and so that refs resolve before the parent life cycles.
30881-
flushSync(function () {
30882-
updateContainer(null, _this3._mountNode, _this3);
30883-
});
30854+
updateContainerSync(null, this._mountNode, this);
30855+
flushSyncWork();
3088430856
};
3088530857

3088630858
_proto4.render = function render() {
30887-
var _this4 = this;
30859+
var _this = this;
3088830860

3088930861
// This is going to be a placeholder because we don't know what it will
3089030862
// actually resolve to because ART may render canvas, vml or svg tags here.
@@ -30895,7 +30867,7 @@ if (__DEV__) {
3089530867
var Tag = Mode$1.Surface.tagName;
3089630868
return /*#__PURE__*/ React.createElement(Tag, {
3089730869
ref: function (ref) {
30898-
return (_this4._tagRef = ref);
30870+
return (_this._tagRef = ref);
3089930871
},
3090030872
accessKey: props.accessKey,
3090130873
className: props.className,
@@ -30914,33 +30886,33 @@ if (__DEV__) {
3091430886
_inheritsLoose(Text, _React$Component2);
3091530887

3091630888
function Text(props) {
30917-
var _this5;
30889+
var _this2;
3091830890

30919-
_this5 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
30891+
_this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
3092030892
// ref directly.
3092130893

3092230894
["height", "width", "x", "y"].forEach(function (key) {
30923-
Object.defineProperty(_assertThisInitialized(_this5), key, {
30895+
Object.defineProperty(_assertThisInitialized(_this2), key, {
3092430896
get: function () {
3092530897
return this._text ? this._text[key] : undefined;
3092630898
}
3092730899
});
3092830900
});
30929-
return _this5;
30901+
return _this2;
3093030902
}
3093130903

3093230904
var _proto5 = Text.prototype;
3093330905

3093430906
_proto5.render = function render() {
30935-
var _this6 = this;
30907+
var _this3 = this;
3093630908

3093730909
// This means you can't have children that render into strings...
3093830910
var T = TYPES.TEXT;
3093930911
return /*#__PURE__*/ React.createElement(
3094030912
T,
3094130913
_extends({}, this.props, {
3094230914
ref: function (t) {
30943-
return (_this6._text = t);
30915+
return (_this3._text = t);
3094430916
}
3094530917
}),
3094630918
childrenAsString(this.props.children)

0 commit comments

Comments
 (0)