prepareForCommit returns info object to be passed resetAfterCommit
The DOM renderer assumes that resetAfterCommit is called after prepareForCommit without any nested commits in between. That may not be the case now that syncUpdates forces a nested update. To address, this changes the type of prepareForCommit to return a value which is later passed to resetAfterCommit.
Andrew Clark committed
Dec 28, 2016 at 21:57 UTC
79f01b242531bc3706c7f254871eb37e43f60e85
8 files changed
+30
-26
scripts/fiber/tests-passing.txt
+2
@@ -1207,6 +1207,7 @@ src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js
1207
* can opt-in to deferred/animation scheduling inside componentDidMount/Update
1208
* performs Task work even after time runs out
1209
* does not perform animation work after time runs out
1210
+* can force synchronous updates with syncUpdates, even inside batchedUpdates
1211
1212
src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
1213
* can update child nodes of a host instance
@@ -1576,6 +1577,7 @@ src/renderers/shared/shared/__tests__/ReactUpdates-test.js
1577
* unstable_batchedUpdates should return value from a callback
1578
* unmounts and remounts a root in the same batch
1579
* handles reentrant mounting in synchronous mode
1580
+* mounts and unmounts are sync even in a batch
1581
1582
src/renderers/shared/shared/__tests__/refs-destruction-test.js
1583
* should remove refs when destroying the parent
src/renderers/dom/fiber/ReactDOMFiber.js
+13
-11
@@ -67,9 +67,10 @@ type HostContextDev = {
67
};
68
type HostContextProd = string;
69
type HostContext = HostContextDev | HostContextProd;
70
-
71
-let eventsEnabled : ?boolean = null;
72
-let selectionInformation : ?mixed = null;
70
+type CommitInfo = {
71
+ eventsEnabled: boolean,
72
+ selectionInformation: mixed,
73
+};
74
75
var ELEMENT_NODE_TYPE = 1;
76
var DOC_NODE_TYPE = 9;
@@ -137,17 +138,18 @@ var DOMRenderer = ReactFiberReconciler({
138
return getChildNamespace(parentNamespace, type);
139
},
140
140
- prepareForCommit() : void {
141
- eventsEnabled = ReactBrowserEventEmitter.isEnabled();
141
+ prepareForCommit() : CommitInfo {
142
+ const eventsEnabled = ReactBrowserEventEmitter.isEnabled();
143
ReactBrowserEventEmitter.setEnabled(false);
143
- selectionInformation = ReactInputSelection.getSelectionInformation();
144
+ return {
145
+ eventsEnabled,
146
+ selectionInformation: ReactInputSelection.getSelectionInformation(),
147
+ };
148
},
149
146
- resetAfterCommit() : void {
147
- ReactInputSelection.restoreSelection(selectionInformation);
148
- selectionInformation = null;
149
- ReactBrowserEventEmitter.setEnabled(eventsEnabled);
150
- eventsEnabled = null;
150
+ resetAfterCommit(commitInfo : CommitInfo) : void {
151
+ ReactInputSelection.restoreSelection(commitInfo.selectionInformation);
152
+ ReactBrowserEventEmitter.setEnabled(commitInfo.eventsEnabled);
153
},
154
155
createInstance(
src/renderers/shared/fiber/ReactFiberBeginWork.js
+2
-2
@@ -66,8 +66,8 @@ if (__DEV__) {
66
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
67
}
68
69
-module.exports = function<T, P, I, TI, C, CX>(
70
- config : HostConfig<T, P, I, TI, C, CX>,
69
+module.exports = function<T, P, I, TI, C, CX, CI>(
70
+ config : HostConfig<T, P, I, TI, C, CX, CI>,
71
hostContext : HostContext<C, CX>,
72
scheduleUpdate : (fiber : Fiber, priorityLevel : PriorityLevel) => void,
73
getPriorityContext : () => PriorityLevel,
src/renderers/shared/fiber/ReactFiberCommitWork.js
+2
-2
@@ -33,8 +33,8 @@ var {
33
ContentReset,
34
} = require('ReactTypeOfSideEffect');
35
36
-module.exports = function<T, P, I, TI, C, CX>(
37
- config : HostConfig<T, P, I, TI, C, CX>,
36
+module.exports = function<T, P, I, TI, C, CX, CI>(
37
+ config : HostConfig<T, P, I, TI, C, CX, CI>,
38
hostContext : HostContext<C, CX>,
39
captureError : (failedFiber : Fiber, error: Error) => ?Fiber
40
) {
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+2
-2
@@ -46,8 +46,8 @@ if (__DEV__) {
46
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
47
}
48
49
-module.exports = function<T, P, I, TI, C, CX>(
50
- config : HostConfig<T, P, I, TI, C, CX>,
49
+module.exports = function<T, P, I, TI, C, CX, CI>(
50
+ config : HostConfig<T, P, I, TI, C, CX, CI>,
51
hostContext : HostContext<C, CX>,
52
) {
53
const {
src/renderers/shared/fiber/ReactFiberHostContext.js
+2
-2
@@ -34,8 +34,8 @@ export type HostContext<C, CX> = {
34
resetHostContainer() : void,
35
};
36
37
-module.exports = function<T, P, I, TI, C, CX>(
38
- config : HostConfig<T, P, I, TI, C, CX>
37
+module.exports = function<T, P, I, TI, C, CX, CI>(
38
+ config : HostConfig<T, P, I, TI, C, CX, CI>
39
) : HostContext<C, CX> {
40
const {
41
getChildHostContext,
src/renderers/shared/fiber/ReactFiberReconciler.js
+4
-4
@@ -43,7 +43,7 @@ export type Deadline = {
43
44
type OpaqueNode = Fiber;
45
46
-export type HostConfig<T, P, I, TI, C, CX> = {
46
+export type HostConfig<T, P, I, TI, C, CX, CI> = {
47
48
getRootHostContext(rootContainerInstance : C) : CX,
49
getChildHostContext(parentHostContext : CX, type : T) : CX,
@@ -69,8 +69,8 @@ export type HostConfig<T, P, I, TI, C, CX> = {
69
scheduleAnimationCallback(callback : () => void) : void,
70
scheduleDeferredCallback(callback : (deadline : Deadline) => void) : void,
71
72
- prepareForCommit() : void,
73
- resetAfterCommit() : void,
72
+ prepareForCommit() : CI,
73
+ resetAfterCommit(commitInfo : CI) : void,
74
75
useSyncScheduling ?: boolean,
76
};
@@ -100,7 +100,7 @@ getContextForSubtree._injectFiber(function(fiber : Fiber) {
100
parentContext;
101
});
102
103
-module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C, CX>) : Reconciler<C, I, TI> {
103
+module.exports = function<T, P, I, TI, C, CX, CI>(config : HostConfig<T, P, I, TI, C, CX, CI>) : Reconciler<C, I, TI> {
104
105
var {
106
scheduleUpdate,
src/renderers/shared/fiber/ReactFiberScheduler.js
+3
-3
@@ -74,7 +74,7 @@ if (__DEV__) {
74
75
var timeHeuristicForUnitOfWork = 1;
76
77
-module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C, CX>) {
77
+module.exports = function<T, P, I, TI, C, CX, CI>(config : HostConfig<T, P, I, TI, C, CX, CI>) {
78
const hostContext = ReactFiberHostContext(config);
79
const { popHostContainer, popHostContext, resetHostContainer } = hostContext;
80
const { beginWork, beginFailedWork } = ReactFiberBeginWork(
@@ -348,7 +348,7 @@ module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C
348
firstEffect = finishedWork.firstEffect;
349
}
350
351
- prepareForCommit();
351
+ const commitInfo = prepareForCommit();
352
353
// Commit all the side-effects within a tree. We'll do this in two passes.
354
// The first pass performs all the host insertions, updates, deletions and
@@ -369,7 +369,7 @@ module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C
369
}
370
}
371
372
- resetAfterCommit();
372
+ resetAfterCommit(commitInfo);
373
374
// In the second pass we'll perform all life-cycles and ref callbacks.
375
// Life-cycles happen as a separate pass so that all placements, updates,