Skip to content

Commit d8eb27e

Browse files
committed
Tie MultiChild queue to ReactReconcileTransaction
Fixes facebook#1147. This now forces all DOM operations for a subtree to be applied when the calling `setState` or `React.renderComponent` call returns (when updates aren't being batched). This means that we can't batch innerHTML setting across different component hierarchies, but our strategy for doing so before seems flawed. It could be possible to make the old way work but it would require making setState always async even when batching isn't in play and refactoring DOMChildrenOperations to not be confused by multiple updates to the same node.
1 parent f9ad17d commit d8eb27e

File tree

6 files changed

+257
-182
lines changed

6 files changed

+257
-182
lines changed

src/browser/ReactReconcileTransaction.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var CallbackQueue = require('CallbackQueue');
2323
var PooledClass = require('PooledClass');
2424
var ReactEventEmitter = require('ReactEventEmitter');
2525
var ReactInputSelection = require('ReactInputSelection');
26+
var ReactMultiChildUpdateQueue = require('ReactMultiChildUpdateQueue');
2627
var ReactPutListenerQueue = require('ReactPutListenerQueue');
2728
var Transaction = require('Transaction');
2829

@@ -98,12 +99,23 @@ var PUT_LISTENER_QUEUEING = {
9899
}
99100
};
100101

102+
var MULTI_CHILD_UPDATE_QUEUEING = {
103+
initialize: function() {
104+
this.multiChildUpdateQueue.reset();
105+
},
106+
107+
close: function() {
108+
this.multiChildUpdateQueue.processUpdates();
109+
}
110+
};
111+
101112
/**
102113
* Executed within the scope of the `Transaction` instance. Consider these as
103114
* being member methods, but with an implied ordering while being isolated from
104115
* each other.
105116
*/
106117
var TRANSACTION_WRAPPERS = [
118+
MULTI_CHILD_UPDATE_QUEUEING,
107119
PUT_LISTENER_QUEUEING,
108120
SELECTION_RESTORATION,
109121
EVENT_SUPPRESSION,
@@ -134,6 +146,7 @@ function ReactReconcileTransaction() {
134146
this.renderToStaticMarkup = false;
135147
this.reactMountReady = CallbackQueue.getPooled(null);
136148
this.putListenerQueue = ReactPutListenerQueue.getPooled();
149+
this.multiChildUpdateQueue = ReactMultiChildUpdateQueue.getPooled();
137150
}
138151

139152
var Mixin = {
@@ -159,6 +172,10 @@ var Mixin = {
159172
return this.putListenerQueue;
160173
},
161174

175+
getMultiChildUpdateQueue: function() {
176+
return this.multiChildUpdateQueue;
177+
},
178+
162179
/**
163180
* `PooledClass` looks for this, and will invoke this before allowing this
164181
* instance to be resused.

src/browser/ui/ReactDOMComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,12 @@ ReactDOMComponent.Mixin = {
377377
if (lastChildren != null && nextChildren == null) {
378378
this.updateChildren(null, transaction);
379379
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
380-
this.updateTextContent('');
380+
this.updateTextContent('', transaction);
381381
}
382382

383383
if (nextContent != null) {
384384
if (lastContent !== nextContent) {
385-
this.updateTextContent('' + nextContent);
385+
this.updateTextContent('' + nextContent, transaction);
386386
}
387387
} else if (nextHtml != null) {
388388
if (lastHtml !== nextHtml) {

src/browser/ui/__tests__/ReactDOMComponent-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ describe('ReactDOMComponent', function() {
157157

158158
expect(stub.getDOMNode().innerHTML).toEqual(':)');
159159
stub.receiveComponent({props: {}}, transaction);
160+
transaction.getMultiChildUpdateQueue().processUpdates();
160161
expect(stub.getDOMNode().innerHTML).toEqual('');
161162
});
162163

@@ -180,6 +181,7 @@ describe('ReactDOMComponent', function() {
180181

181182
expect(stub.getDOMNode().innerHTML).toEqual('bonjour');
182183
stub.receiveComponent({props: {children: 'adieu'}}, transaction);
184+
transaction.getMultiChildUpdateQueue().processUpdates();
183185
expect(stub.getDOMNode().innerHTML).toEqual('adieu');
184186
});
185187

0 commit comments

Comments
 (0)