From 29c1e1deba7bee3a230f122a558161f026063b74 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 20 Dec 2016 13:07:47 -0800 Subject: [PATCH 1/2] Schedule state and callback in the same batch Fixes an issue (in both Stack and Fiber) where enqueueSetState causes a synchronous update that flushes before enqueueCallback is ever called. Now enqueueSetState et al accept an optional callback so that both are scheduled at the same time. --- src/isomorphic/classic/class/ReactClass.js | 5 +- src/isomorphic/modern/class/ReactComponent.js | 10 +--- .../shared/fiber/ReactFiberBeginWork.js | 13 ++--- .../shared/fiber/ReactFiberClassComponent.js | 32 ++++++++---- .../shared/fiber/ReactFiberReconciler.js | 25 +++++---- .../shared/fiber/ReactFiberScheduler.js | 52 +++++-------------- .../shared/fiber/ReactFiberUpdateQueue.js | 28 +++++++--- .../ReactCompositeComponentState-test.js | 25 ++------- .../shared/__tests__/ReactUpdates-test.js | 10 ++-- .../stack/reconciler/ReactUpdateQueue.js | 39 ++++++++++++-- 10 files changed, 121 insertions(+), 118 deletions(-) diff --git a/src/isomorphic/classic/class/ReactClass.js b/src/isomorphic/classic/class/ReactClass.js index 475f08d7d8..f7cc206fd0 100644 --- a/src/isomorphic/classic/class/ReactClass.js +++ b/src/isomorphic/classic/class/ReactClass.js @@ -728,10 +728,7 @@ var ReactClassMixin = { * type signature and the only use case for this, is to avoid that. */ replaceState: function(newState, callback) { - this.updater.enqueueReplaceState(this, newState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'replaceState'); - } + this.updater.enqueueReplaceState(this, newState, callback, 'replaceState'); }, /** diff --git a/src/isomorphic/modern/class/ReactComponent.js b/src/isomorphic/modern/class/ReactComponent.js index b93da63e94..48c5af86a3 100644 --- a/src/isomorphic/modern/class/ReactComponent.js +++ b/src/isomorphic/modern/class/ReactComponent.js @@ -65,10 +65,7 @@ ReactComponent.prototype.setState = function(partialState, callback) { 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.' ); - this.updater.enqueueSetState(this, partialState); - if (callback) { - this.updater.enqueueCallback(this, callback, 'setState'); - } + this.updater.enqueueSetState(this, partialState, callback, 'setState'); }; /** @@ -86,10 +83,7 @@ ReactComponent.prototype.setState = function(partialState, callback) { * @protected */ ReactComponent.prototype.forceUpdate = function(callback) { - this.updater.enqueueForceUpdate(this); - if (callback) { - this.updater.enqueueCallback(this, callback, 'forceUpdate'); - } + this.updater.enqueueForceUpdate(this, callback, 'forceUpdate'); }; /** diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index f7442c7bbd..17142c6a06 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -71,10 +71,8 @@ if (__DEV__) { module.exports = function( config : HostConfig, hostContext : HostContext, - scheduleSetState: (fiber : Fiber, partialState : any) => void, - scheduleReplaceState: (fiber : Fiber, state : any) => void, - scheduleForceUpdate: (fiber : Fiber) => void, - scheduleUpdateCallback: (fiber : Fiber, callback : Function) => void, + scheduleUpdate : (fiber : Fiber, priorityLevel : PriorityLevel) => void, + getPriorityContext : () => PriorityLevel, ) { const { shouldSetTextContent } = config; @@ -91,12 +89,7 @@ module.exports = function( mountClassInstance, resumeMountClassInstance, updateClassInstance, - } = ReactFiberClassComponent( - scheduleSetState, - scheduleReplaceState, - scheduleForceUpdate, - scheduleUpdateCallback - ); + } = ReactFiberClassComponent(scheduleUpdate, getPriorityContext); function markChildAsProgressed(current, workInProgress, priorityLevel) { // We now have clones. Let's store them as the currently progressed work. diff --git a/src/renderers/shared/fiber/ReactFiberClassComponent.js b/src/renderers/shared/fiber/ReactFiberClassComponent.js index b8813947b0..39c8102487 100644 --- a/src/renderers/shared/fiber/ReactFiberClassComponent.js +++ b/src/renderers/shared/fiber/ReactFiberClassComponent.js @@ -19,6 +19,10 @@ var { getMaskedContext, } = require('ReactFiberContext'); var { + addUpdate, + addReplaceUpdate, + addForceUpdate, + addCallback, beginUpdateQueue, } = require('ReactFiberUpdateQueue'); var { hasContextChanged } = require('ReactFiberContext'); @@ -31,30 +35,36 @@ var invariant = require('invariant'); const isArray = Array.isArray; module.exports = function( - scheduleSetState: (fiber : Fiber, partialState : any) => void, - scheduleReplaceState: (fiber : Fiber, state : any) => void, - scheduleForceUpdate: (fiber : Fiber) => void, - scheduleUpdateCallback: (fiber : Fiber, callback : Function) => void, + scheduleUpdate : (fiber : Fiber, priorityLevel : PriorityLevel) => void, + getPriorityContext : () => PriorityLevel, ) { // Class component state updater const updater = { isMounted, - enqueueSetState(instance, partialState) { + enqueueSetState(instance, partialState, callback) { const fiber = ReactInstanceMap.get(instance); - scheduleSetState(fiber, partialState); + const priorityLevel = getPriorityContext(); + addUpdate(fiber, partialState, callback || null, priorityLevel); + scheduleUpdate(fiber, priorityLevel); }, - enqueueReplaceState(instance, state) { + enqueueReplaceState(instance, state, callback) { const fiber = ReactInstanceMap.get(instance); - scheduleReplaceState(fiber, state); + const priorityLevel = getPriorityContext(); + addReplaceUpdate(fiber, state, callback || null, priorityLevel); + scheduleUpdate(fiber, priorityLevel); }, - enqueueForceUpdate(instance) { + enqueueForceUpdate(instance, callback) { const fiber = ReactInstanceMap.get(instance); - scheduleForceUpdate(fiber); + const priorityLevel = getPriorityContext(); + addForceUpdate(fiber, callback || null, priorityLevel); + scheduleUpdate(fiber, priorityLevel); }, enqueueCallback(instance, callback) { const fiber = ReactInstanceMap.get(instance); - scheduleUpdateCallback(fiber, callback); + const priorityLevel = getPriorityContext(); + addCallback(fiber, callback || null, priorityLevel); + scheduleUpdate(fiber, priorityLevel); }, }; diff --git a/src/renderers/shared/fiber/ReactFiberReconciler.js b/src/renderers/shared/fiber/ReactFiberReconciler.js index d81bee1ebd..2b63d3c5f9 100644 --- a/src/renderers/shared/fiber/ReactFiberReconciler.js +++ b/src/renderers/shared/fiber/ReactFiberReconciler.js @@ -17,6 +17,10 @@ import type { FiberRoot } from 'ReactFiberRoot'; import type { PriorityLevel } from 'ReactPriorityLevel'; import type { ReactNodeList } from 'ReactTypes'; +var { + addTopLevelUpdate, +} = require('ReactFiberUpdateQueue'); + var { findCurrentUnmaskedContext, isContextProvider, @@ -98,14 +102,21 @@ getContextForSubtree._injectFiber(function(fiber : Fiber) { module.exports = function(config : HostConfig) : Reconciler { var { - scheduleTopLevelSetState, - scheduleUpdateCallback, + scheduleUpdate, + getPriorityContext, performWithPriority, batchedUpdates, syncUpdates, deferredUpdates, } = ReactFiberScheduler(config); + function scheduleTopLevelUpdate(current : Fiber, element : ReactNodeList, callback : ?Function) { + const priorityLevel = getPriorityContext(); + const nextState = { element }; + addTopLevelUpdate(current, nextState, callback || null, priorityLevel); + scheduleUpdate(current, priorityLevel); + } + return { mountContainer(element : ReactNodeList, containerInfo : C, parentComponent : ?ReactComponent, callback: ?Function) : OpaqueNode { @@ -113,10 +124,7 @@ module.exports = function(config : HostConfig(config : HostConfig(config : HostConfig(config : HostConfig(config : HostConfig(config : HostConfig | null, + callback : Callback | null, priorityLevel : PriorityLevel ) : void { const update = { priorityLevel, partialState, - callback: null, + callback, isReplace: false, isForced: false, isTopLevelUnmount: false, @@ -306,12 +307,13 @@ exports.addUpdate = addUpdate; function addReplaceUpdate( fiber : Fiber, state : any | null, + callback : Callback | null, priorityLevel : PriorityLevel ) : void { const update = { priorityLevel, partialState: state, - callback: null, + callback, isReplace: true, isForced: false, isTopLevelUnmount: false, @@ -326,11 +328,15 @@ function addReplaceUpdate( } exports.addReplaceUpdate = addReplaceUpdate; -function addForceUpdate(fiber : Fiber, priorityLevel : PriorityLevel) : void { +function addForceUpdate( + fiber : Fiber, + callback : Callback | null, + priorityLevel : PriorityLevel +) : void { const update = { priorityLevel, partialState: null, - callback: null, + callback, isReplace: false, isForced: true, isTopLevelUnmount: false, @@ -345,7 +351,11 @@ function addForceUpdate(fiber : Fiber, priorityLevel : PriorityLevel) : void { exports.addForceUpdate = addForceUpdate; -function addCallback(fiber : Fiber, callback: Callback, priorityLevel : PriorityLevel) : void { +function addCallback( + fiber : Fiber, + callback: Callback, + priorityLevel : PriorityLevel +) : void { const update : Update = { priorityLevel, partialState: null, @@ -367,14 +377,18 @@ exports.getPendingPriority = getPendingPriority; function addTopLevelUpdate( fiber : Fiber, partialState : PartialState, + callback : Callback | null, priorityLevel : PriorityLevel ) : void { - const isTopLevelUnmount = partialState === null; + const isTopLevelUnmount = Boolean( + partialState && + partialState.element === null + ); const update = { priorityLevel, partialState, - callback: null, + callback, isReplace: false, isForced: false, isTopLevelUnmount, diff --git a/src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js b/src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js index 446fafe747..d9e884cf89 100644 --- a/src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js +++ b/src/renderers/shared/shared/__tests__/ReactCompositeComponentState-test.js @@ -171,20 +171,8 @@ describe('ReactCompositeComponent-state', () => { ['componentDidMount-end', 'orange'], ['setState-sunrise', 'orange'], ['setState-orange', 'orange'], - ]; - - // In Fiber, the initial callback is not enqueued until after any work - // scheduled by lifecycles has flushed (same semantics as a regular setState - // callback outside of a batch). In Stack, the initial render is scheduled - // inside of batchedUpdates, so the callback gets flushed right after - // componentDidMount. - // TODO: We should fix this, in both Stack and Fiber, so that the behavior - // is consistent regardless of whether you're in a batch. - if (!ReactDOMFeatureFlags.useFiber) { - expected.push(['initial-callback', 'orange']); - } - - expected.push(['shouldComponentUpdate-currentState', 'orange'], + ['initial-callback', 'orange'], + ['shouldComponentUpdate-currentState', 'orange'], ['shouldComponentUpdate-nextState', 'yellow'], ['componentWillUpdate-currentState', 'orange'], ['componentWillUpdate-nextState', 'yellow'], @@ -192,18 +180,11 @@ describe('ReactCompositeComponent-state', () => { ['componentDidUpdate-currentState', 'yellow'], ['componentDidUpdate-prevState', 'orange'], ['setState-yellow', 'yellow'], - ); - - if (ReactDOMFeatureFlags.useFiber) { - expected.push(['initial-callback', 'yellow']); - } - - expected.push( ['componentWillReceiveProps-start', 'yellow'], // setState({color:'green'}) only enqueues a pending state. ['componentWillReceiveProps-end', 'yellow'], // pending state queue is processed - ); + ]; if (ReactDOMFeatureFlags.useFiber) { // In Stack, this is never called because replaceState drops all updates diff --git a/src/renderers/shared/shared/__tests__/ReactUpdates-test.js b/src/renderers/shared/shared/__tests__/ReactUpdates-test.js index 31b9a84acf..a68f875abd 100644 --- a/src/renderers/shared/shared/__tests__/ReactUpdates-test.js +++ b/src/renderers/shared/shared/__tests__/ReactUpdates-test.js @@ -648,16 +648,18 @@ describe('ReactUpdates', () => { 'Inner-render-1-0', 'Inner-didUpdate-1-0', 'Outer-didUpdate-1', + // Happens in a batch, so don't re-render yet 'Inner-setState-1', - 'Inner-render-1-1', - 'Inner-didUpdate-1-1', - 'Inner-callback-1', 'Outer-callback-1', - 'Outer-setState-2', + // Happens in a batch + 'Outer-setState-2', + + // Flush batched updates all at once 'Outer-render-2', 'Inner-render-2-1', 'Inner-didUpdate-2-1', + 'Inner-callback-1', 'Outer-didUpdate-2', 'Inner-setState-2', 'Outer-callback-2', diff --git a/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js b/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js index 1b555520a7..55d95b77c3 100644 --- a/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js +++ b/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js @@ -166,9 +166,11 @@ var ReactUpdateQueue = { * `componentWillUpdate` and `componentDidUpdate`. * * @param {ReactClass} publicInstance The instance that should rerender. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueForceUpdate: function(publicInstance) { + enqueueForceUpdate: function(publicInstance, callback, callerName) { var internalInstance = getInternalInstanceReadyForUpdate( publicInstance, 'forceUpdate' @@ -178,6 +180,15 @@ var ReactUpdateQueue = { return; } + if (callback) { + ReactUpdateQueue.validateCallback(callback, callerName); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + } + internalInstance._pendingForceUpdate = true; enqueueUpdate(internalInstance); @@ -192,9 +203,11 @@ var ReactUpdateQueue = { * * @param {ReactClass} publicInstance The instance that should rerender. * @param {object} completeState Next state. + * @param {?function} callback Called after state is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueReplaceState: function(publicInstance, completeState) { + enqueueReplaceState: function(publicInstance, completeState, callback, callerName) { var internalInstance = getInternalInstanceReadyForUpdate( publicInstance, 'replaceState' @@ -207,6 +220,15 @@ var ReactUpdateQueue = { internalInstance._pendingStateQueue = [completeState]; internalInstance._pendingReplaceState = true; + if (callback) { + ReactUpdateQueue.validateCallback(callback, callerName); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + } + enqueueUpdate(internalInstance); }, @@ -218,9 +240,11 @@ var ReactUpdateQueue = { * * @param {ReactClass} publicInstance The instance that should rerender. * @param {object} partialState Next partial state to be merged with state. + * @param {?function} callback Called after state is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueSetState: function(publicInstance, partialState) { + enqueueSetState: function(publicInstance, partialState, callback, callerName) { if (__DEV__) { ReactInstrumentation.debugTool.onSetState(); warning( @@ -244,6 +268,15 @@ var ReactUpdateQueue = { (internalInstance._pendingStateQueue = []); queue.push(partialState); + if (callback) { + ReactUpdateQueue.validateCallback(callback, callerName); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + } + enqueueUpdate(internalInstance); }, From f4c0c9997362730c2b5182d6a7db19e5e4f9fee5 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 21 Dec 2016 13:03:39 -0600 Subject: [PATCH 2/2] Remove enqueueCallback from updater API This isn't being used anymore. Also removes addCallback from ReactFiberUpdateQueue. --- .../modern/class/ReactNoopUpdateQueue.js | 22 +++++----- .../stack/server/ReactServerUpdateQueue.js | 40 +++++++++---------- .../shared/fiber/ReactFiberClassComponent.js | 7 ---- .../shared/fiber/ReactFiberUpdateQueue.js | 19 --------- .../stack/reconciler/ReactUpdateQueue.js | 34 ---------------- 5 files changed, 29 insertions(+), 93 deletions(-) diff --git a/src/isomorphic/modern/class/ReactNoopUpdateQueue.js b/src/isomorphic/modern/class/ReactNoopUpdateQueue.js index 49d4c72660..7e657e1425 100644 --- a/src/isomorphic/modern/class/ReactNoopUpdateQueue.js +++ b/src/isomorphic/modern/class/ReactNoopUpdateQueue.js @@ -44,16 +44,6 @@ var ReactNoopUpdateQueue = { return false; }, - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function(publicInstance, callback) { }, - /** * Forces an update. This should only be invoked when it is known with * certainty that we are **not** in a DOM transaction. @@ -65,9 +55,11 @@ var ReactNoopUpdateQueue = { * `componentWillUpdate` and `componentDidUpdate`. * * @param {ReactClass} publicInstance The instance that should rerender. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueForceUpdate: function(publicInstance) { + enqueueForceUpdate: function(publicInstance, callback, callerName) { warnNoop(publicInstance, 'forceUpdate'); }, @@ -80,9 +72,11 @@ var ReactNoopUpdateQueue = { * * @param {ReactClass} publicInstance The instance that should rerender. * @param {object} completeState Next state. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueReplaceState: function(publicInstance, completeState) { + enqueueReplaceState: function(publicInstance, completeState, callback, callerName) { warnNoop(publicInstance, 'replaceState'); }, @@ -94,9 +88,11 @@ var ReactNoopUpdateQueue = { * * @param {ReactClass} publicInstance The instance that should rerender. * @param {object} partialState Next partial state to be merged with state. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueSetState: function(publicInstance, partialState) { + enqueueSetState: function(publicInstance, partialState, callback, callerName) { warnNoop(publicInstance, 'setState'); }, }; diff --git a/src/renderers/dom/stack/server/ReactServerUpdateQueue.js b/src/renderers/dom/stack/server/ReactServerUpdateQueue.js index b1e6a54c2e..546c9c967e 100644 --- a/src/renderers/dom/stack/server/ReactServerUpdateQueue.js +++ b/src/renderers/dom/stack/server/ReactServerUpdateQueue.js @@ -58,20 +58,6 @@ class ReactServerUpdateQueue { return false; } - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback(publicInstance: ReactComponent, callback?: Function, callerName?: string) { - if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueCallback(publicInstance, callback, callerName); - } - } - /** * Forces an update. This should only be invoked when it is known with * certainty that we are **not** in a DOM transaction. @@ -83,11 +69,13 @@ class ReactServerUpdateQueue { * `componentWillUpdate` and `componentDidUpdate`. * * @param {ReactClass} publicInstance The instance that should rerender. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueForceUpdate(publicInstance: ReactComponent) { + enqueueForceUpdate(publicInstance: ReactComponent, callback?: Function, callerName?: string) { if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueForceUpdate(publicInstance); + ReactUpdateQueue.enqueueForceUpdate(publicInstance, callback, callerName); } else { warnNoop(publicInstance, 'forceUpdate'); } @@ -102,11 +90,18 @@ class ReactServerUpdateQueue { * * @param {ReactClass} publicInstance The instance that should rerender. * @param {object|function} completeState Next state. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. * @internal */ - enqueueReplaceState(publicInstance: ReactComponent, completeState: Object|Function) { + enqueueReplaceState( + publicInstance: ReactComponent, + completeState: Object|Function, + callback?: Function, + callerName?: string + ) { if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState); + ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState, callback, callerName); } else { warnNoop(publicInstance, 'replaceState'); } @@ -122,9 +117,14 @@ class ReactServerUpdateQueue { * @param {object|function} partialState Next partial state to be merged with state. * @internal */ - enqueueSetState(publicInstance: ReactComponent, partialState: Object|Function) { + enqueueSetState( + publicInstance: ReactComponent, + partialState: Object|Function, + callback?: Function, + callerName?: string + ) { if (this.transaction.isInTransaction()) { - ReactUpdateQueue.enqueueSetState(publicInstance, partialState); + ReactUpdateQueue.enqueueSetState(publicInstance, partialState, callback, callerName); } else { warnNoop(publicInstance, 'setState'); } diff --git a/src/renderers/shared/fiber/ReactFiberClassComponent.js b/src/renderers/shared/fiber/ReactFiberClassComponent.js index 39c8102487..99e9a08416 100644 --- a/src/renderers/shared/fiber/ReactFiberClassComponent.js +++ b/src/renderers/shared/fiber/ReactFiberClassComponent.js @@ -22,7 +22,6 @@ var { addUpdate, addReplaceUpdate, addForceUpdate, - addCallback, beginUpdateQueue, } = require('ReactFiberUpdateQueue'); var { hasContextChanged } = require('ReactFiberContext'); @@ -60,12 +59,6 @@ module.exports = function( addForceUpdate(fiber, callback || null, priorityLevel); scheduleUpdate(fiber, priorityLevel); }, - enqueueCallback(instance, callback) { - const fiber = ReactInstanceMap.get(instance); - const priorityLevel = getPriorityContext(); - addCallback(fiber, callback || null, priorityLevel); - scheduleUpdate(fiber, priorityLevel); - }, }; function checkShouldComponentUpdate(workInProgress, oldProps, newProps, newState, newContext) { diff --git a/src/renderers/shared/fiber/ReactFiberUpdateQueue.js b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js index effa273ed6..fdabc5e9d8 100644 --- a/src/renderers/shared/fiber/ReactFiberUpdateQueue.js +++ b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js @@ -350,25 +350,6 @@ function addForceUpdate( } exports.addForceUpdate = addForceUpdate; - -function addCallback( - fiber : Fiber, - callback: Callback, - priorityLevel : PriorityLevel -) : void { - const update : Update = { - priorityLevel, - partialState: null, - callback, - isReplace: false, - isForced: false, - isTopLevelUnmount: false, - next: null, - }; - insertUpdate(fiber, update); -} -exports.addCallback = addCallback; - function getPendingPriority(queue : UpdateQueue) : PriorityLevel { return queue.first ? queue.first.priorityLevel : NoWork; } diff --git a/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js b/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js index 55d95b77c3..dc9b881a5e 100644 --- a/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js +++ b/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js @@ -112,40 +112,6 @@ var ReactUpdateQueue = { } }, - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @param {string} callerName Name of the calling function in the public API. - * @internal - */ - enqueueCallback: function(publicInstance, callback, callerName) { - ReactUpdateQueue.validateCallback(callback, callerName); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - enqueueCallbackInternal: function(internalInstance, callback) { if (internalInstance._pendingCallbacks) { internalInstance._pendingCallbacks.push(callback);