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 c56a44b5b28e1..c749ed37ab64d 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 a4ed6d3e547bd..26c373490987a 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 4cfb1f4bb1b32..e5ee7a831d18a 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 bb56a4c78f3bd..429e892e0bef5 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 bffecb3c4690e..8c836cfda5d21 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 529271de6ad35..de311124ca9e6 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 ff55cbddaa008..3424ef683faa8 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 e78d1c40ee1c7..20603ec6889e5 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