react 15.2.1 → 15.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/ReactDOM.js CHANGED
@@ -27,7 +27,7 @@ var warning = require('fbjs/lib/warning');
27
27
 
28
28
  ReactDefaultInjection.inject();
29
29
 
30
- var React = {
30
+ var ReactDOM = {
31
31
  findDOMNode: findDOMNode,
32
32
  render: ReactMount.render,
33
33
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
@@ -98,4 +98,4 @@ if (process.env.NODE_ENV !== 'production') {
98
98
  }
99
99
  }
100
100
 
101
- module.exports = React;
101
+ module.exports = ReactDOM;
@@ -411,6 +411,8 @@ ReactDOMComponent.Mixin = {
411
411
  * @return {string} The computed markup.
412
412
  */
413
413
  mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
414
+ var _this = this;
415
+
414
416
  this._rootNodeID = globalIdCounter++;
415
417
  this._domID = hostContainerInfo._idCounter++;
416
418
  this._hostParent = hostParent;
@@ -566,6 +568,15 @@ ReactDOMComponent.Mixin = {
566
568
  break;
567
569
  }
568
570
 
571
+ if (process.env.NODE_ENV !== 'production') {
572
+ if (this._debugID) {
573
+ var callback = function () {
574
+ return ReactInstrumentation.debugTool.onComponentHasMounted(_this._debugID);
575
+ };
576
+ transaction.getReactMountReady().enqueue(callback, this);
577
+ }
578
+ }
579
+
569
580
  return mountImage;
570
581
  },
571
582
 
@@ -734,6 +745,8 @@ ReactDOMComponent.Mixin = {
734
745
  * @overridable
735
746
  */
736
747
  updateComponent: function (transaction, prevElement, nextElement, context) {
748
+ var _this2 = this;
749
+
737
750
  var lastProps = prevElement.props;
738
751
  var nextProps = this._currentElement.props;
739
752
 
@@ -771,6 +784,15 @@ ReactDOMComponent.Mixin = {
771
784
  // reconciliation
772
785
  transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
773
786
  }
787
+
788
+ if (process.env.NODE_ENV !== 'production') {
789
+ if (this._debugID) {
790
+ var callback = function () {
791
+ return ReactInstrumentation.debugTool.onComponentHasUpdated(_this2._debugID);
792
+ };
793
+ transaction.getReactMountReady().enqueue(callback, this);
794
+ }
795
+ }
774
796
  },
775
797
 
776
798
  /**
@@ -66,7 +66,10 @@ var ReactDOMInput = {
66
66
  var hostProps = _assign({
67
67
  // Make sure we set .type before any other properties (setting .value
68
68
  // before .type means .value is lost in IE11 and below)
69
- type: undefined
69
+ type: undefined,
70
+ // Make sure we set .step before .value (setting .value before .step
71
+ // means .value is rounded on mount, based upon step precision)
72
+ step: undefined
70
73
  }, DisabledInputUtils.getHostProps(inst, props), {
71
74
  defaultChecked: undefined,
72
75
  defaultValue: undefined,
@@ -14,6 +14,7 @@
14
14
  var ReactInvalidSetStateWarningDevTool = require('./ReactInvalidSetStateWarningDevTool');
15
15
  var ReactHostOperationHistoryDevtool = require('./ReactHostOperationHistoryDevtool');
16
16
  var ReactComponentTreeDevtool = require('./ReactComponentTreeDevtool');
17
+ var ReactChildrenMutationWarningDevtool = require('./ReactChildrenMutationWarningDevtool');
17
18
  var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
18
19
 
19
20
  var performanceNow = require('fbjs/lib/performanceNow');
@@ -46,6 +47,8 @@ var currentTimerStartTime = null;
46
47
  var currentTimerNestedFlushDuration = null;
47
48
  var currentTimerType = null;
48
49
 
50
+ var lifeCycleTimerHasWarned = false;
51
+
49
52
  function clearHistory() {
50
53
  ReactComponentTreeDevtool.purgeUnmountedComponents();
51
54
  ReactHostOperationHistoryDevtool.clearHistory();
@@ -103,7 +106,10 @@ function beginLifeCycleTimer(debugID, timerType) {
103
106
  if (currentFlushNesting === 0) {
104
107
  return;
105
108
  }
106
- process.env.NODE_ENV !== 'production' ? warning(!currentTimerType, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
109
+ if (currentTimerType && !lifeCycleTimerHasWarned) {
110
+ process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
111
+ lifeCycleTimerHasWarned = true;
112
+ }
107
113
  currentTimerStartTime = performanceNow();
108
114
  currentTimerNestedFlushDuration = 0;
109
115
  currentTimerDebugID = debugID;
@@ -114,7 +120,10 @@ function endLifeCycleTimer(debugID, timerType) {
114
120
  if (currentFlushNesting === 0) {
115
121
  return;
116
122
  }
117
- process.env.NODE_ENV !== 'production' ? warning(currentTimerType === timerType, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
123
+ if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) {
124
+ process.env.NODE_ENV !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
125
+ lifeCycleTimerHasWarned = true;
126
+ }
118
127
  if (isProfiling) {
119
128
  currentFlushMeasurements.push({
120
129
  timerType: timerType,
@@ -240,6 +249,14 @@ var ReactDebugTool = {
240
249
  checkDebugID(debugID);
241
250
  emitEvent('onHostOperation', debugID, type, payload);
242
251
  },
252
+ onComponentHasMounted: function (debugID) {
253
+ checkDebugID(debugID);
254
+ emitEvent('onComponentHasMounted', debugID);
255
+ },
256
+ onComponentHasUpdated: function (debugID) {
257
+ checkDebugID(debugID);
258
+ emitEvent('onComponentHasUpdated', debugID);
259
+ },
243
260
  onSetState: function () {
244
261
  emitEvent('onSetState');
245
262
  },
@@ -295,6 +312,7 @@ var ReactDebugTool = {
295
312
 
296
313
  ReactDebugTool.addDevtool(ReactInvalidSetStateWarningDevTool);
297
314
  ReactDebugTool.addDevtool(ReactComponentTreeDevtool);
315
+ ReactDebugTool.addDevtool(ReactChildrenMutationWarningDevtool);
298
316
  var url = ExecutionEnvironment.canUseDOM && window.location.href || '';
299
317
  if (/[?&]react_perf\b/.test(url)) {
300
318
  ReactDebugTool.beginProfiling();
@@ -97,6 +97,7 @@ var ReactElement = function (type, key, ref, self, source, owner, props) {
97
97
  // This can be replaced with a WeakMap once they are implemented in
98
98
  // commonly used development environments.
99
99
  element._store = {};
100
+ var shadowChildren = Array.isArray(props.children) ? props.children.slice(0) : props.children;
100
101
 
101
102
  // To make comparing ReactElements easier for testing purposes, we make
102
103
  // the validation flag non-enumerable (where possible, which should
@@ -116,6 +117,12 @@ var ReactElement = function (type, key, ref, self, source, owner, props) {
116
117
  writable: false,
117
118
  value: self
118
119
  });
120
+ Object.defineProperty(element, '_shadowChildren', {
121
+ configurable: false,
122
+ enumerable: false,
123
+ writable: false,
124
+ value: shadowChildren
125
+ });
119
126
  // Two elements created in two different places should be considered
120
127
  // equal for testing purposes and therefore we hide it from enumeration.
121
128
  Object.defineProperty(element, '_source', {
@@ -127,6 +134,7 @@ var ReactElement = function (type, key, ref, self, source, owner, props) {
127
134
  } else {
128
135
  element._store.validated = false;
129
136
  element._self = self;
137
+ element._shadowChildren = shadowChildren;
130
138
  element._source = source;
131
139
  }
132
140
  if (Object.freeze) {
@@ -200,7 +200,7 @@ var ReactMultiChild = {
200
200
  return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);
201
201
  },
202
202
 
203
- _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, removedNodes, transaction, context) {
203
+ _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) {
204
204
  var nextChildren;
205
205
  if (process.env.NODE_ENV !== 'production') {
206
206
  if (this._currentElement) {
@@ -210,12 +210,12 @@ var ReactMultiChild = {
210
210
  } finally {
211
211
  ReactCurrentOwner.current = null;
212
212
  }
213
- ReactChildReconciler.updateChildren(prevChildren, nextChildren, removedNodes, transaction, context);
213
+ ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context);
214
214
  return nextChildren;
215
215
  }
216
216
  }
217
217
  nextChildren = flattenChildren(nextNestedChildrenElements);
218
- ReactChildReconciler.updateChildren(prevChildren, nextChildren, removedNodes, transaction, context);
218
+ ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context);
219
219
  return nextChildren;
220
220
  },
221
221
 
@@ -312,7 +312,8 @@ var ReactMultiChild = {
312
312
  _updateChildren: function (nextNestedChildrenElements, transaction, context) {
313
313
  var prevChildren = this._renderedChildren;
314
314
  var removedNodes = {};
315
- var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, removedNodes, transaction, context);
315
+ var mountImages = [];
316
+ var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context);
316
317
  if (!nextChildren && !prevChildren) {
317
318
  return;
318
319
  }
@@ -320,8 +321,10 @@ var ReactMultiChild = {
320
321
  var name;
321
322
  // `nextIndex` will increment for each child in `nextChildren`, but
322
323
  // `lastIndex` will be the last index visited in `prevChildren`.
323
- var lastIndex = 0;
324
324
  var nextIndex = 0;
325
+ var lastIndex = 0;
326
+ // `nextMountIndex` will increment for each newly mounted child.
327
+ var nextMountIndex = 0;
325
328
  var lastPlacedNode = null;
326
329
  for (name in nextChildren) {
327
330
  if (!nextChildren.hasOwnProperty(name)) {
@@ -340,7 +343,8 @@ var ReactMultiChild = {
340
343
  // The `removedNodes` loop below will actually remove the child.
341
344
  }
342
345
  // The child must be instantiated before it's mounted.
343
- updates = enqueue(updates, this._mountChildAtIndex(nextChild, lastPlacedNode, nextIndex, transaction, context));
346
+ updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context));
347
+ nextMountIndex++;
344
348
  }
345
349
  nextIndex++;
346
350
  lastPlacedNode = ReactReconciler.getHostNode(nextChild);
@@ -423,8 +427,7 @@ var ReactMultiChild = {
423
427
  * @param {ReactReconcileTransaction} transaction
424
428
  * @private
425
429
  */
426
- _mountChildAtIndex: function (child, afterNode, index, transaction, context) {
427
- var mountImage = ReactReconciler.mountComponent(child, transaction, this, this._hostContainerInfo, context);
430
+ _mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) {
428
431
  child._mountIndex = index;
429
432
  return this.createChild(child, afterNode, mountImage);
430
433
  },
@@ -13,9 +13,11 @@
13
13
 
14
14
  var ReactElement = require('./ReactElement');
15
15
  var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
16
+ var ReactPropTypesSecret = require('./ReactPropTypesSecret');
16
17
 
17
18
  var emptyFunction = require('fbjs/lib/emptyFunction');
18
19
  var getIteratorFn = require('./getIteratorFn');
20
+ var warning = require('fbjs/lib/warning');
19
21
 
20
22
  /**
21
23
  * Collection of methods that allow declaration and validation of props that are
@@ -105,9 +107,21 @@ function is(x, y) {
105
107
  /*eslint-enable no-self-compare*/
106
108
 
107
109
  function createChainableTypeChecker(validate) {
108
- function checkType(isRequired, props, propName, componentName, location, propFullName) {
110
+ if (process.env.NODE_ENV !== 'production') {
111
+ var manualPropTypeCallCache = {};
112
+ }
113
+ function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
109
114
  componentName = componentName || ANONYMOUS;
110
115
  propFullName = propFullName || propName;
116
+ if (process.env.NODE_ENV !== 'production') {
117
+ if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') {
118
+ var cacheKey = componentName + ':' + propName;
119
+ if (!manualPropTypeCallCache[cacheKey]) {
120
+ process.env.NODE_ENV !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in the next major version. You may be ' + 'seeing this warning due to a third-party PropTypes library. ' + 'See https://fb.me/react-warning-dont-call-proptypes for details.', propFullName, componentName) : void 0;
121
+ manualPropTypeCallCache[cacheKey] = true;
122
+ }
123
+ }
124
+ }
111
125
  if (props[propName] == null) {
112
126
  var locationName = ReactPropTypeLocationNames[location];
113
127
  if (isRequired) {
@@ -126,7 +140,7 @@ function createChainableTypeChecker(validate) {
126
140
  }
127
141
 
128
142
  function createPrimitiveTypeChecker(expectedType) {
129
- function validate(props, propName, componentName, location, propFullName) {
143
+ function validate(props, propName, componentName, location, propFullName, secret) {
130
144
  var propValue = props[propName];
131
145
  var propType = getPropType(propValue);
132
146
  if (propType !== expectedType) {
@@ -159,7 +173,7 @@ function createArrayOfTypeChecker(typeChecker) {
159
173
  return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
160
174
  }
161
175
  for (var i = 0; i < propValue.length; i++) {
162
- var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']');
176
+ var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);
163
177
  if (error instanceof Error) {
164
178
  return error;
165
179
  }
@@ -171,9 +185,11 @@ function createArrayOfTypeChecker(typeChecker) {
171
185
 
172
186
  function createElementTypeChecker() {
173
187
  function validate(props, propName, componentName, location, propFullName) {
174
- if (!ReactElement.isValidElement(props[propName])) {
188
+ var propValue = props[propName];
189
+ if (!ReactElement.isValidElement(propValue)) {
175
190
  var locationName = ReactPropTypeLocationNames[location];
176
- return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a single ReactElement.'));
191
+ var propType = getPropType(propValue);
192
+ return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
177
193
  }
178
194
  return null;
179
195
  }
@@ -195,9 +211,8 @@ function createInstanceTypeChecker(expectedClass) {
195
211
 
196
212
  function createEnumTypeChecker(expectedValues) {
197
213
  if (!Array.isArray(expectedValues)) {
198
- return createChainableTypeChecker(function () {
199
- return new Error('Invalid argument supplied to oneOf, expected an instance of array.');
200
- });
214
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0;
215
+ return emptyFunction.thatReturnsNull;
201
216
  }
202
217
 
203
218
  function validate(props, propName, componentName, location, propFullName) {
@@ -228,7 +243,7 @@ function createObjectOfTypeChecker(typeChecker) {
228
243
  }
229
244
  for (var key in propValue) {
230
245
  if (propValue.hasOwnProperty(key)) {
231
- var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key);
246
+ var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
232
247
  if (error instanceof Error) {
233
248
  return error;
234
249
  }
@@ -241,15 +256,14 @@ function createObjectOfTypeChecker(typeChecker) {
241
256
 
242
257
  function createUnionTypeChecker(arrayOfTypeCheckers) {
243
258
  if (!Array.isArray(arrayOfTypeCheckers)) {
244
- return createChainableTypeChecker(function () {
245
- return new Error('Invalid argument supplied to oneOfType, expected an instance of array.');
246
- });
259
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
260
+ return emptyFunction.thatReturnsNull;
247
261
  }
248
262
 
249
263
  function validate(props, propName, componentName, location, propFullName) {
250
264
  for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
251
265
  var checker = arrayOfTypeCheckers[i];
252
- if (checker(props, propName, componentName, location, propFullName) == null) {
266
+ if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) {
253
267
  return null;
254
268
  }
255
269
  }
@@ -284,7 +298,7 @@ function createShapeTypeChecker(shapeTypes) {
284
298
  if (!checker) {
285
299
  continue;
286
300
  }
287
- var error = checker(propValue, key, componentName, location, propFullName + '.' + key);
301
+ var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
288
302
  if (error) {
289
303
  return error;
290
304
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactPropTypesSecret
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
15
+
16
+ module.exports = ReactPropTypesSecret;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactPureComponent
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var _assign = require('object-assign');
15
+
16
+ var ReactComponent = require('./ReactComponent');
17
+ var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue');
18
+
19
+ var emptyObject = require('fbjs/lib/emptyObject');
20
+
21
+ /**
22
+ * Base class helpers for the updating state of a component.
23
+ */
24
+ function ReactPureComponent(props, context, updater) {
25
+ // Duplicated from ReactComponent.
26
+ this.props = props;
27
+ this.context = context;
28
+ this.refs = emptyObject;
29
+ // We initialize the default updater but the real one gets injected by the
30
+ // renderer.
31
+ this.updater = updater || ReactNoopUpdateQueue;
32
+ }
33
+
34
+ function ComponentDummy() {}
35
+ ComponentDummy.prototype = ReactComponent.prototype;
36
+ ReactPureComponent.prototype = new ComponentDummy();
37
+ ReactPureComponent.prototype.constructor = ReactPureComponent;
38
+ // Avoid an extra prototype jump for these methods.
39
+ _assign(ReactPureComponent.prototype, ReactComponent.prototype);
40
+ ReactPureComponent.prototype.isPureReactComponent = true;
41
+
42
+ module.exports = ReactPureComponent;
@@ -11,12 +11,10 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var _prodInvariant = require('./reactProdInvariant');
15
-
16
14
  var ReactRef = require('./ReactRef');
17
15
  var ReactInstrumentation = require('./ReactInstrumentation');
18
16
 
19
- var invariant = require('fbjs/lib/invariant');
17
+ var warning = require('fbjs/lib/warning');
20
18
 
21
19
  /**
22
20
  * Helper to call ReactRef.attachRefs with this composite component, split out
@@ -153,7 +151,7 @@ var ReactReconciler = {
153
151
  if (internalInstance._updateBatchNumber !== updateBatchNumber) {
154
152
  // The component's enqueued batch number should always be the current
155
153
  // batch or the following one.
156
- !(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'performUpdateIfNecessary: Unexpected batch number (current %s, pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : _prodInvariant('121', updateBatchNumber, internalInstance._updateBatchNumber) : void 0;
154
+ process.env.NODE_ENV !== 'production' ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0;
157
155
  return;
158
156
  }
159
157
  if (process.env.NODE_ENV !== 'production') {
package/lib/ReactRef.js CHANGED
@@ -61,7 +61,9 @@ ReactRef.shouldUpdateRefs = function (prevElement, nextElement) {
61
61
 
62
62
  return(
63
63
  // This has a few false positives w/r/t empty components.
64
- prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref
64
+ prevEmpty || nextEmpty || nextElement.ref !== prevElement.ref ||
65
+ // If owner changes but we have an unchanged function ref, don't update refs
66
+ typeof nextElement.ref === 'string' && nextElement._owner !== prevElement._owner
65
67
  );
66
68
  };
67
69
 
@@ -26,6 +26,8 @@ var emptyObject = require('fbjs/lib/emptyObject');
26
26
  var instantiateReactComponent = require('./instantiateReactComponent');
27
27
  var invariant = require('fbjs/lib/invariant');
28
28
 
29
+ var pendingTransactions = 0;
30
+
29
31
  /**
30
32
  * @param {ReactElement} element
31
33
  * @return {string} the HTML markup
@@ -37,6 +39,8 @@ function renderToStringImpl(element, makeStaticMarkup) {
37
39
 
38
40
  transaction = ReactServerRenderingTransaction.getPooled(makeStaticMarkup);
39
41
 
42
+ pendingTransactions++;
43
+
40
44
  return transaction.perform(function () {
41
45
  var componentInstance = instantiateReactComponent(element, true);
42
46
  var markup = ReactReconciler.mountComponent(componentInstance, transaction, null, ReactDOMContainerInfo(), emptyObject);
@@ -49,10 +53,13 @@ function renderToStringImpl(element, makeStaticMarkup) {
49
53
  return markup;
50
54
  }, null);
51
55
  } finally {
56
+ pendingTransactions--;
52
57
  ReactServerRenderingTransaction.release(transaction);
53
58
  // Revert to the DOM batching strategy since these two renderers
54
59
  // currently share these stateful modules.
55
- ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
60
+ if (!pendingTransactions) {
61
+ ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
62
+ }
56
63
  }
57
64
  }
58
65