Merge pull request #2935 from sebmarkbage/batchupdates

Batch updates in initial render
This commit is contained in:
Sebastian Markbåge
2015-01-27 01:06:56 -08:00
5 changed files with 46 additions and 19 deletions
+2 -2
View File
@@ -31,8 +31,8 @@ var ReactRAFBatchingStrategy = {
* Call the provided function in a context within which calls to `setState`
* and friends are batched such that components aren't updated unnecessarily.
*/
batchedUpdates: function(callback, a, b) {
callback(a, b);
batchedUpdates: function(callback, a, b, c, d) {
callback(a, b, c, d);
}
};
+36 -7
View File
@@ -233,23 +233,51 @@ function findDeepestCachedAncestor(targetID) {
/**
* Mounts this component and inserts it into the DOM.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {string} rootID DOM ID of the root node.
* @param {DOMElement} container DOM element to mount into.
* @param {ReactReconcileTransaction} transaction
* @param {boolean} shouldReuseMarkup If true, do not insert markup
*/
function mountComponentIntoNode(
componentInstance,
rootID,
container,
transaction,
shouldReuseMarkup) {
var markup = ReactReconciler.mountComponent(
this, rootID, transaction, emptyObject
componentInstance, rootID, transaction, emptyObject
);
this._isTopLevel = true;
componentInstance._isTopLevel = true;
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
}
/**
* Batched mount.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {string} rootID DOM ID of the root node.
* @param {DOMElement} container DOM element to mount into.
* @param {boolean} shouldReuseMarkup If true, do not insert markup
*/
function batchedMountComponentIntoNode(
componentInstance,
rootID,
container,
shouldReuseMarkup) {
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
transaction.perform(
mountComponentIntoNode,
null,
componentInstance,
rootID,
container,
transaction,
shouldReuseMarkup
);
ReactUpdates.ReactReconcileTransaction.release(transaction);
}
/**
* Mounting is the process of initializing a React component by creatings its
* representative DOM elements and inserting them into a supplied `container`.
@@ -368,16 +396,17 @@ var ReactMount = {
container
);
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
transaction.perform(
mountComponentIntoNode,
// The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched
// according to the current batching strategy.
ReactUpdates.batchedUpdates(
batchedMountComponentIntoNode,
componentInstance,
reactRootID,
container,
transaction,
shouldReuseMarkup
);
ReactUpdates.ReactReconcileTransaction.release(transaction);
if (__DEV__) {
// Record the root element in case it later gets transplanted.
+3 -3
View File
@@ -54,16 +54,16 @@ var ReactDefaultBatchingStrategy = {
* Call the provided function in a context within which calls to `setState`
* and friends are batched such that components aren't updated unnecessarily.
*/
batchedUpdates: function(callback, a, b) {
batchedUpdates: function(callback, a, b, c, d) {
var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
ReactDefaultBatchingStrategy.isBatchingUpdates = true;
// The code is written this way to avoid extra allocations
if (alreadyBatchingUpdates) {
callback(a, b);
callback(a, b, c, d);
} else {
transaction.perform(callback, null, a, b);
transaction.perform(callback, null, a, b, c, d);
}
}
};
+2 -2
View File
@@ -104,9 +104,9 @@ assign(
PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
function batchedUpdates(callback, a, b) {
function batchedUpdates(callback, a, b, c, d) {
ensureInjected();
batchingStrategy.batchedUpdates(callback, a, b);
batchingStrategy.batchedUpdates(callback, a, b, c, d);
}
/**
@@ -155,9 +155,9 @@ describe('ReactCompositeComponent-state', function() {
[ 'componentDidMount-start', 'orange', null ],
// setState-sunrise and setState-orange should be called here,
// after the bug in #1740
// componentDidMount() called setState({color:'yellow'}), currently this
// occurs inline.
// In a future where setState() is async, this test result will change.
// componentDidMount() called setState({color:'yellow'}), which is async.
// The update doesn't happen until the next flush.
[ 'componentDidMount-end', 'orange', 'yellow' ],
[ 'shouldComponentUpdate-currentState', 'orange', null ],
[ 'shouldComponentUpdate-nextState', 'yellow' ],
[ 'componentWillUpdate-currentState', 'orange', null ],
@@ -166,8 +166,6 @@ describe('ReactCompositeComponent-state', function() {
[ 'componentDidUpdate-currentState', 'yellow', null ],
[ 'componentDidUpdate-prevState', 'orange' ],
[ 'setState-yellow', 'yellow', null ],
// componentDidMount() finally closes.
[ 'componentDidMount-end', 'yellow', null ],
[ 'initial-callback', 'yellow', null ],
[ 'componentWillReceiveProps-start', 'yellow', null ],
// setState({color:'green'}) only enqueues a pending state.