From 79f01b242531bc3706c7f254871eb37e43f60e85 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 28 Dec 2016 21:57:34 -0800 Subject: [PATCH] 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. --- scripts/fiber/tests-passing.txt | 2 ++ src/renderers/dom/fiber/ReactDOMFiber.js | 24 ++++++++++--------- .../shared/fiber/ReactFiberBeginWork.js | 4 ++-- .../shared/fiber/ReactFiberCommitWork.js | 4 ++-- .../shared/fiber/ReactFiberCompleteWork.js | 4 ++-- .../shared/fiber/ReactFiberHostContext.js | 4 ++-- .../shared/fiber/ReactFiberReconciler.js | 8 +++---- .../shared/fiber/ReactFiberScheduler.js | 6 ++--- 8 files changed, 30 insertions(+), 26 deletions(-) diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt index c56a44b5b2..c749ed37ab 100644 --- a/scripts/fiber/tests-passing.txt +++ b/scripts/fiber/tests-passing.txt @@ -1207,6 +1207,7 @@ src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js * can opt-in to deferred/animation scheduling inside componentDidMount/Update * performs Task work even after time runs out * does not perform animation work after time runs out +* can force synchronous updates with syncUpdates, even inside batchedUpdates src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js * can update child nodes of a host instance @@ -1576,6 +1577,7 @@ src/renderers/shared/shared/__tests__/ReactUpdates-test.js * unstable_batchedUpdates should return value from a callback * unmounts and remounts a root in the same batch * handles reentrant mounting in synchronous mode +* mounts and unmounts are sync even in a batch src/renderers/shared/shared/__tests__/refs-destruction-test.js * should remove refs when destroying the parent diff --git a/src/renderers/dom/fiber/ReactDOMFiber.js b/src/renderers/dom/fiber/ReactDOMFiber.js index a4ed6d3e54..26c3734909 100644 --- a/src/renderers/dom/fiber/ReactDOMFiber.js +++ b/src/renderers/dom/fiber/ReactDOMFiber.js @@ -67,9 +67,10 @@ type HostContextDev = { }; type HostContextProd = string; type HostContext = HostContextDev | HostContextProd; - -let eventsEnabled : ?boolean = null; -let selectionInformation : ?mixed = null; +type CommitInfo = { + eventsEnabled: boolean, + selectionInformation: mixed, +}; var ELEMENT_NODE_TYPE = 1; var DOC_NODE_TYPE = 9; @@ -137,17 +138,18 @@ var DOMRenderer = ReactFiberReconciler({ return getChildNamespace(parentNamespace, type); }, - prepareForCommit() : void { - eventsEnabled = ReactBrowserEventEmitter.isEnabled(); + prepareForCommit() : CommitInfo { + const eventsEnabled = ReactBrowserEventEmitter.isEnabled(); ReactBrowserEventEmitter.setEnabled(false); - selectionInformation = ReactInputSelection.getSelectionInformation(); + return { + eventsEnabled, + selectionInformation: ReactInputSelection.getSelectionInformation(), + }; }, - resetAfterCommit() : void { - ReactInputSelection.restoreSelection(selectionInformation); - selectionInformation = null; - ReactBrowserEventEmitter.setEnabled(eventsEnabled); - eventsEnabled = null; + resetAfterCommit(commitInfo : CommitInfo) : void { + ReactInputSelection.restoreSelection(commitInfo.selectionInformation); + ReactBrowserEventEmitter.setEnabled(commitInfo.eventsEnabled); }, createInstance( diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index 4cfb1f4bb1..e5ee7a831d 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -66,8 +66,8 @@ if (__DEV__) { var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber'); } -module.exports = function( - config : HostConfig, +module.exports = function( + config : HostConfig, hostContext : HostContext, scheduleUpdate : (fiber : Fiber, priorityLevel : PriorityLevel) => void, getPriorityContext : () => PriorityLevel, diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js index bb56a4c78f..429e892e0b 100644 --- a/src/renderers/shared/fiber/ReactFiberCommitWork.js +++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js @@ -33,8 +33,8 @@ var { ContentReset, } = require('ReactTypeOfSideEffect'); -module.exports = function( - config : HostConfig, +module.exports = function( + config : HostConfig, hostContext : HostContext, captureError : (failedFiber : Fiber, error: Error) => ?Fiber ) { diff --git a/src/renderers/shared/fiber/ReactFiberCompleteWork.js b/src/renderers/shared/fiber/ReactFiberCompleteWork.js index bffecb3c46..8c836cfda5 100644 --- a/src/renderers/shared/fiber/ReactFiberCompleteWork.js +++ b/src/renderers/shared/fiber/ReactFiberCompleteWork.js @@ -46,8 +46,8 @@ if (__DEV__) { var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber'); } -module.exports = function( - config : HostConfig, +module.exports = function( + config : HostConfig, hostContext : HostContext, ) { const { diff --git a/src/renderers/shared/fiber/ReactFiberHostContext.js b/src/renderers/shared/fiber/ReactFiberHostContext.js index 529271de6a..de311124ca 100644 --- a/src/renderers/shared/fiber/ReactFiberHostContext.js +++ b/src/renderers/shared/fiber/ReactFiberHostContext.js @@ -34,8 +34,8 @@ export type HostContext = { resetHostContainer() : void, }; -module.exports = function( - config : HostConfig +module.exports = function( + config : HostConfig ) : HostContext { const { getChildHostContext, diff --git a/src/renderers/shared/fiber/ReactFiberReconciler.js b/src/renderers/shared/fiber/ReactFiberReconciler.js index ff55cbddaa..3424ef683f 100644 --- a/src/renderers/shared/fiber/ReactFiberReconciler.js +++ b/src/renderers/shared/fiber/ReactFiberReconciler.js @@ -43,7 +43,7 @@ export type Deadline = { type OpaqueNode = Fiber; -export type HostConfig = { +export type HostConfig = { getRootHostContext(rootContainerInstance : C) : CX, getChildHostContext(parentHostContext : CX, type : T) : CX, @@ -69,8 +69,8 @@ export type HostConfig = { scheduleAnimationCallback(callback : () => void) : void, scheduleDeferredCallback(callback : (deadline : Deadline) => void) : void, - prepareForCommit() : void, - resetAfterCommit() : void, + prepareForCommit() : CI, + resetAfterCommit(commitInfo : CI) : void, useSyncScheduling ?: boolean, }; @@ -100,7 +100,7 @@ getContextForSubtree._injectFiber(function(fiber : Fiber) { parentContext; }); -module.exports = function(config : HostConfig) : Reconciler { +module.exports = function(config : HostConfig) : Reconciler { var { scheduleUpdate, diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index e78d1c40ee..20603ec688 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -74,7 +74,7 @@ if (__DEV__) { var timeHeuristicForUnitOfWork = 1; -module.exports = function(config : HostConfig) { +module.exports = function(config : HostConfig) { const hostContext = ReactFiberHostContext(config); const { popHostContainer, popHostContext, resetHostContainer } = hostContext; const { beginWork, beginFailedWork } = ReactFiberBeginWork( @@ -348,7 +348,7 @@ module.exports = function(config : HostConfig(config : HostConfig