react 0.10.0 → 0.11.2

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.
Files changed (104) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +20344 -0
  3. package/dist/react-with-addons.js +20276 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18484 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/BeforeInputEventPlugin.js +222 -0
  8. package/lib/CSSPropertyOperations.js +3 -3
  9. package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
  10. package/lib/ChangeEventPlugin.js +1 -1
  11. package/lib/CompositionEventPlugin.js +5 -1
  12. package/lib/DOMChildrenOperations.js +21 -14
  13. package/lib/DOMProperty.js +45 -17
  14. package/lib/DOMPropertyOperations.js +22 -10
  15. package/lib/DefaultEventPluginOrder.js +1 -0
  16. package/lib/EventConstants.js +1 -0
  17. package/lib/EventListener.js +5 -2
  18. package/lib/EventPluginHub.js +0 -5
  19. package/lib/EventPluginRegistry.js +6 -4
  20. package/lib/EventPluginUtils.js +11 -1
  21. package/lib/ExecutionEnvironment.js +8 -2
  22. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +42 -49
  23. package/lib/LinkedValueUtils.js +21 -22
  24. package/lib/LocalEventTrapMixin.js +52 -0
  25. package/lib/React.js +57 -3
  26. package/lib/ReactBrowserComponentMixin.js +4 -0
  27. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
  28. package/lib/ReactCSSTransitionGroup.js +2 -0
  29. package/lib/ReactCSSTransitionGroupChild.js +2 -5
  30. package/lib/ReactChildren.js +31 -10
  31. package/lib/ReactComponent.js +88 -237
  32. package/lib/ReactComponentBrowserEnvironment.js +3 -2
  33. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  34. package/lib/ReactCompositeComponent.js +222 -384
  35. package/lib/ReactDOM.js +22 -18
  36. package/lib/ReactDOMComponent.js +26 -24
  37. package/lib/ReactDOMForm.js +5 -13
  38. package/lib/ReactDOMIDOperations.js +2 -31
  39. package/lib/ReactDOMImg.js +5 -14
  40. package/lib/ReactDOMSelect.js +16 -15
  41. package/lib/ReactDOMSelection.js +35 -10
  42. package/lib/ReactDOMTextarea.js +2 -4
  43. package/lib/ReactDefaultBatchingStrategy.js +3 -3
  44. package/lib/ReactDefaultInjection.js +18 -15
  45. package/lib/ReactDefaultPerf.js +28 -11
  46. package/lib/ReactDefaultPerfAnalysis.js +4 -0
  47. package/lib/ReactDescriptor.js +251 -0
  48. package/lib/ReactDescriptorValidator.js +283 -0
  49. package/lib/ReactEmptyComponent.js +78 -0
  50. package/lib/ReactEventEmitterMixin.js +1 -3
  51. package/lib/ReactEventListener.js +189 -0
  52. package/lib/ReactInjection.js +4 -2
  53. package/lib/ReactLink.js +24 -0
  54. package/lib/ReactMount.js +51 -19
  55. package/lib/ReactMultiChild.js +9 -11
  56. package/lib/ReactPropTransferer.js +44 -29
  57. package/lib/ReactPropTypes.js +226 -242
  58. package/lib/ReactPutListenerQueue.js +2 -2
  59. package/lib/ReactReconcileTransaction.js +14 -14
  60. package/lib/ReactServerRendering.js +5 -5
  61. package/lib/ReactServerRenderingTransaction.js +4 -5
  62. package/lib/ReactTestUtils.js +39 -21
  63. package/lib/ReactTextComponent.js +8 -22
  64. package/lib/ReactTransitionChildMapping.js +2 -2
  65. package/lib/ReactTransitionEvents.js +19 -0
  66. package/lib/ReactTransitionGroup.js +9 -6
  67. package/lib/ReactUpdates.js +139 -22
  68. package/lib/ReactWithAddons.js +5 -2
  69. package/lib/SVGDOMPropertyConfig.js +97 -0
  70. package/lib/SimpleEventPlugin.js +7 -1
  71. package/lib/SyntheticInputEvent.js +52 -0
  72. package/lib/SyntheticKeyboardEvent.js +33 -4
  73. package/lib/SyntheticMouseEvent.js +3 -0
  74. package/lib/SyntheticTouchEvent.js +4 -1
  75. package/lib/SyntheticUIEvent.js +24 -2
  76. package/lib/Transaction.js +0 -32
  77. package/lib/cloneWithProps.js +3 -1
  78. package/lib/createFullPageComponent.js +1 -1
  79. package/lib/dangerousStyleValue.js +11 -5
  80. package/lib/escapeTextForBrowser.js +2 -3
  81. package/lib/flattenChildren.js +9 -7
  82. package/lib/getEventKey.js +35 -5
  83. package/lib/getEventModifierState.js +52 -0
  84. package/lib/getMarkupWrap.js +2 -0
  85. package/lib/getTextContentAccessor.js +1 -1
  86. package/lib/hyphenate.js +3 -0
  87. package/lib/hyphenateStyleName.js +46 -0
  88. package/lib/instantiateReactComponent.js +13 -21
  89. package/lib/invariant.js +17 -19
  90. package/lib/{objMap.js → mapObject.js} +8 -3
  91. package/lib/mergeHelpers.js +11 -0
  92. package/lib/mergeInto.js +3 -2
  93. package/lib/onlyChild.js +3 -3
  94. package/lib/performance.js +33 -0
  95. package/lib/performanceNow.js +5 -14
  96. package/lib/setInnerHTML.js +85 -0
  97. package/lib/shouldUpdateReactComponent.js +12 -29
  98. package/lib/toArray.js +1 -1
  99. package/lib/traverseAllChildren.js +7 -4
  100. package/lib/update.js +57 -45
  101. package/package.json +4 -3
  102. package/lib/ReactEventTopLevelCallback.js +0 -149
  103. package/lib/createObjectFrom.js +0 -61
  104. package/lib/objMapKeyVal.js +0 -47
@@ -25,6 +25,8 @@ var ReactTransitionGroup = require("./ReactTransitionGroup");
25
25
  var ReactCSSTransitionGroupChild = require("./ReactCSSTransitionGroupChild");
26
26
 
27
27
  var ReactCSSTransitionGroup = React.createClass({
28
+ displayName: 'ReactCSSTransitionGroup',
29
+
28
30
  propTypes: {
29
31
  transitionName: React.PropTypes.string.isRequired,
30
32
  transitionEnter: React.PropTypes.bool,
@@ -48,6 +48,8 @@ if ("production" !== process.env.NODE_ENV) {
48
48
  }
49
49
 
50
50
  var ReactCSSTransitionGroupChild = React.createClass({
51
+ displayName: 'ReactCSSTransitionGroupChild',
52
+
51
53
  transition: function(animationType, finishCallback) {
52
54
  var node = this.getDOMNode();
53
55
  var className = this.props.name + '-' + animationType;
@@ -84,11 +86,6 @@ var ReactCSSTransitionGroupChild = React.createClass({
84
86
  queueClass: function(className) {
85
87
  this.classNameQueue.push(className);
86
88
 
87
- if (this.props.runNextTick) {
88
- this.props.runNextTick(this.flushClassNameQueue);
89
- return;
90
- }
91
-
92
89
  if (!this.timeout) {
93
90
  this.timeout = setTimeout(this.flushClassNameQueue, TICK);
94
91
  }
@@ -20,8 +20,8 @@
20
20
 
21
21
  var PooledClass = require("./PooledClass");
22
22
 
23
- var invariant = require("./invariant");
24
23
  var traverseAllChildren = require("./traverseAllChildren");
24
+ var warning = require("./warning");
25
25
 
26
26
  var twoArgumentPooler = PooledClass.twoArgumentPooler;
27
27
  var threeArgumentPooler = PooledClass.threeArgumentPooler;
@@ -86,16 +86,21 @@ PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
86
86
  function mapSingleChildIntoContext(traverseContext, child, name, i) {
87
87
  var mapBookKeeping = traverseContext;
88
88
  var mapResult = mapBookKeeping.mapResult;
89
- var mappedChild =
90
- mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
91
- // We found a component instance
92
- ("production" !== process.env.NODE_ENV ? invariant(
93
- !mapResult.hasOwnProperty(name),
89
+
90
+ var keyUnique = !mapResult.hasOwnProperty(name);
91
+ ("production" !== process.env.NODE_ENV ? warning(
92
+ keyUnique,
94
93
  'ReactChildren.map(...): Encountered two children with the same key, ' +
95
- '`%s`. Children keys must be unique.',
94
+ '`%s`. Child keys must be unique; when two children share a key, only ' +
95
+ 'the first child will be used.',
96
96
  name
97
- ) : invariant(!mapResult.hasOwnProperty(name)));
98
- mapResult[name] = mappedChild;
97
+ ) : null);
98
+
99
+ if (keyUnique) {
100
+ var mappedChild =
101
+ mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
102
+ mapResult[name] = mappedChild;
103
+ }
99
104
  }
100
105
 
101
106
  /**
@@ -124,9 +129,25 @@ function mapChildren(children, func, context) {
124
129
  return mapResult;
125
130
  }
126
131
 
132
+ function forEachSingleChildDummy(traverseContext, child, name, i) {
133
+ return null;
134
+ }
135
+
136
+ /**
137
+ * Count the number of children that are typically specified as
138
+ * `props.children`.
139
+ *
140
+ * @param {?*} children Children tree container.
141
+ * @return {number} The number of children.
142
+ */
143
+ function countChildren(children, context) {
144
+ return traverseAllChildren(children, forEachSingleChildDummy, null);
145
+ }
146
+
127
147
  var ReactChildren = {
128
148
  forEach: forEachChildren,
129
- map: mapChildren
149
+ map: mapChildren,
150
+ count: countChildren
130
151
  };
131
152
 
132
153
  module.exports = ReactChildren;
@@ -18,14 +18,13 @@
18
18
 
19
19
  "use strict";
20
20
 
21
- var ReactCurrentOwner = require("./ReactCurrentOwner");
21
+ var ReactDescriptor = require("./ReactDescriptor");
22
22
  var ReactOwner = require("./ReactOwner");
23
23
  var ReactUpdates = require("./ReactUpdates");
24
24
 
25
25
  var invariant = require("./invariant");
26
26
  var keyMirror = require("./keyMirror");
27
27
  var merge = require("./merge");
28
- var monitorCodeUse = require("./monitorCodeUse");
29
28
 
30
29
  /**
31
30
  * Every React component is in one of these life cycles.
@@ -42,18 +41,6 @@ var ComponentLifeCycle = keyMirror({
42
41
  UNMOUNTED: null
43
42
  });
44
43
 
45
- /**
46
- * Warn if there's no key explicitly set on dynamic arrays of children or
47
- * object keys are not valid. This allows us to keep track of children between
48
- * updates.
49
- */
50
-
51
- var ownerHasExplicitKeyWarning = {};
52
- var ownerHasPropertyWarning = {};
53
- var ownerHasMonitoredObjectMap = {};
54
-
55
- var NUMERIC_PROPERTY_REGEX = /^\d+$/;
56
-
57
44
  var injected = false;
58
45
 
59
46
  /**
@@ -76,130 +63,6 @@ var unmountIDFromEnvironment = null;
76
63
  */
77
64
  var mountImageIntoNode = null;
78
65
 
79
- /**
80
- * Warn if the component doesn't have an explicit key assigned to it.
81
- * This component is in an array. The array could grow and shrink or be
82
- * reordered. All children that haven't already been validated are required to
83
- * have a "key" property assigned to it.
84
- *
85
- * @internal
86
- * @param {ReactComponent} component Component that requires a key.
87
- */
88
- function validateExplicitKey(component) {
89
- if (component.__keyValidated__ || component.props.key != null) {
90
- return;
91
- }
92
- component.__keyValidated__ = true;
93
-
94
- // We can't provide friendly warnings for top level components.
95
- if (!ReactCurrentOwner.current) {
96
- return;
97
- }
98
-
99
- // Name of the component whose render method tried to pass children.
100
- var currentName = ReactCurrentOwner.current.constructor.displayName;
101
- if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
102
- return;
103
- }
104
- ownerHasExplicitKeyWarning[currentName] = true;
105
-
106
- var message = 'Each child in an array should have a unique "key" prop. ' +
107
- 'Check the render method of ' + currentName + '.';
108
-
109
- var childOwnerName = null;
110
- if (!component.isOwnedBy(ReactCurrentOwner.current)) {
111
- // Name of the component that originally created this child.
112
- childOwnerName =
113
- component._owner &&
114
- component._owner.constructor.displayName;
115
-
116
- // Usually the current owner is the offender, but if it accepts
117
- // children as a property, it may be the creator of the child that's
118
- // responsible for assigning it a key.
119
- message += ' It was passed a child from ' + childOwnerName + '.';
120
- }
121
-
122
- message += ' See http://fb.me/react-warning-keys for more information.';
123
- monitorCodeUse('react_key_warning', {
124
- component: currentName,
125
- componentOwner: childOwnerName
126
- });
127
- console.warn(message);
128
- }
129
-
130
- /**
131
- * Warn if the key is being defined as an object property but has an incorrect
132
- * value.
133
- *
134
- * @internal
135
- * @param {string} name Property name of the key.
136
- * @param {ReactComponent} component Component that requires a key.
137
- */
138
- function validatePropertyKey(name) {
139
- if (NUMERIC_PROPERTY_REGEX.test(name)) {
140
- // Name of the component whose render method tried to pass children.
141
- var currentName = ReactCurrentOwner.current.constructor.displayName;
142
- if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
143
- return;
144
- }
145
- ownerHasPropertyWarning[currentName] = true;
146
-
147
- monitorCodeUse('react_numeric_key_warning');
148
- console.warn(
149
- 'Child objects should have non-numeric keys so ordering is preserved. ' +
150
- 'Check the render method of ' + currentName + '. ' +
151
- 'See http://fb.me/react-warning-keys for more information.'
152
- );
153
- }
154
- }
155
-
156
- /**
157
- * Log that we're using an object map. We're considering deprecating this
158
- * feature and replace it with proper Map and ImmutableMap data structures.
159
- *
160
- * @internal
161
- */
162
- function monitorUseOfObjectMap() {
163
- // Name of the component whose render method tried to pass children.
164
- // We only use this to avoid spewing the logs. We lose additional
165
- // owner stacks but hopefully one level is enough to trace the source.
166
- var currentName = (ReactCurrentOwner.current &&
167
- ReactCurrentOwner.current.constructor.displayName) || '';
168
- if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
169
- return;
170
- }
171
- ownerHasMonitoredObjectMap[currentName] = true;
172
- monitorCodeUse('react_object_map_children');
173
- }
174
-
175
- /**
176
- * Ensure that every component either is passed in a static location, in an
177
- * array with an explicit keys property defined, or in an object literal
178
- * with valid key property.
179
- *
180
- * @internal
181
- * @param {*} component Statically passed child of any type.
182
- * @return {boolean}
183
- */
184
- function validateChildKeys(component) {
185
- if (Array.isArray(component)) {
186
- for (var i = 0; i < component.length; i++) {
187
- var child = component[i];
188
- if (ReactComponent.isValidComponent(child)) {
189
- validateExplicitKey(child);
190
- }
191
- }
192
- } else if (ReactComponent.isValidComponent(component)) {
193
- // This component was passed in a valid location.
194
- component.__keyValidated__ = true;
195
- } else if (component && typeof component === 'object') {
196
- monitorUseOfObjectMap();
197
- for (var name in component) {
198
- validatePropertyKey(name, component);
199
- }
200
- }
201
- }
202
-
203
66
  /**
204
67
  * Components are the basic units of composition in React.
205
68
  *
@@ -238,32 +101,10 @@ var ReactComponent = {
238
101
  ReactComponentEnvironment.unmountIDFromEnvironment;
239
102
  ReactComponent.BackendIDOperations =
240
103
  ReactComponentEnvironment.BackendIDOperations;
241
- ReactComponent.ReactReconcileTransaction =
242
- ReactComponentEnvironment.ReactReconcileTransaction;
243
104
  injected = true;
244
105
  }
245
106
  },
246
107
 
247
- /**
248
- * @param {?object} object
249
- * @return {boolean} True if `object` is a valid component.
250
- * @final
251
- */
252
- isValidComponent: function(object) {
253
- if (!object || !object.type || !object.type.prototype) {
254
- return false;
255
- }
256
- // This is the safer way of duck checking the type of instance this is.
257
- // The object can be a generic descriptor but the type property refers to
258
- // the constructor and it's prototype can be used to inspect the type that
259
- // will actually get mounted.
260
- var prototype = object.type.prototype;
261
- return (
262
- typeof prototype.mountComponentIntoNode === 'function' &&
263
- typeof prototype.receiveComponent === 'function'
264
- );
265
- },
266
-
267
108
  /**
268
109
  * @internal
269
110
  */
@@ -278,14 +119,6 @@ var ReactComponent = {
278
119
  */
279
120
  BackendIDOperations: null,
280
121
 
281
- /**
282
- * React references `ReactReconcileTransaction` using this property in order
283
- * to allow dependency injection.
284
- *
285
- * @internal
286
- */
287
- ReactReconcileTransaction: null,
288
-
289
122
  /**
290
123
  * Base functionality for every ReactComponent constructor. Mixed into the
291
124
  * `ReactComponent` prototype, but exposed statically for easy access.
@@ -314,9 +147,11 @@ var ReactComponent = {
314
147
  * @public
315
148
  */
316
149
  setProps: function(partialProps, callback) {
317
- // Merge with `_pendingProps` if it exists, otherwise with existing props.
150
+ // Merge with the pending descriptor if it exists, otherwise with existing
151
+ // descriptor props.
152
+ var descriptor = this._pendingDescriptor || this._descriptor;
318
153
  this.replaceProps(
319
- merge(this._pendingProps || this.props, partialProps),
154
+ merge(descriptor.props, partialProps),
320
155
  callback
321
156
  );
322
157
  },
@@ -342,7 +177,31 @@ var ReactComponent = {
342
177
  '`render` method to pass the correct value as props to the component ' +
343
178
  'where it is created.'
344
179
  ) : invariant(this._mountDepth === 0));
345
- this._pendingProps = props;
180
+ // This is a deoptimized path. We optimize for always having a descriptor.
181
+ // This creates an extra internal descriptor.
182
+ this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
183
+ this._pendingDescriptor || this._descriptor,
184
+ props
185
+ );
186
+ ReactUpdates.enqueueUpdate(this, callback);
187
+ },
188
+
189
+ /**
190
+ * Schedule a partial update to the props. Only used for internal testing.
191
+ *
192
+ * @param {object} partialProps Subset of the next props.
193
+ * @param {?function} callback Called after props are updated.
194
+ * @final
195
+ * @internal
196
+ */
197
+ _setPropsInternal: function(partialProps, callback) {
198
+ // This is a deoptimized path. We optimize for always having a descriptor.
199
+ // This creates an extra internal descriptor.
200
+ var descriptor = this._pendingDescriptor || this._descriptor;
201
+ this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
202
+ descriptor,
203
+ merge(descriptor.props, partialProps)
204
+ );
346
205
  ReactUpdates.enqueueUpdate(this, callback);
347
206
  },
348
207
 
@@ -352,43 +211,30 @@ var ReactComponent = {
352
211
  * Subclasses that override this method should make sure to invoke
353
212
  * `ReactComponent.Mixin.construct.call(this, ...)`.
354
213
  *
355
- * @param {?object} initialProps
356
- * @param {*} children
214
+ * @param {ReactDescriptor} descriptor
357
215
  * @internal
358
216
  */
359
- construct: function(initialProps, children) {
360
- this.props = initialProps || {};
217
+ construct: function(descriptor) {
218
+ // This is the public exposed props object after it has been processed
219
+ // with default props. The descriptor's props represents the true internal
220
+ // state of the props.
221
+ this.props = descriptor.props;
361
222
  // Record the component responsible for creating this component.
362
- this._owner = ReactCurrentOwner.current;
223
+ // This is accessible through the descriptor but we maintain an extra
224
+ // field for compatibility with devtools and as a way to make an
225
+ // incremental update. TODO: Consider deprecating this field.
226
+ this._owner = descriptor._owner;
227
+
363
228
  // All components start unmounted.
364
229
  this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
365
230
 
366
- this._pendingProps = null;
231
+ // See ReactUpdates.
367
232
  this._pendingCallbacks = null;
368
233
 
369
- // Unlike _pendingProps and _pendingCallbacks, we won't use null to
370
- // indicate that nothing is pending because it's possible for a component
371
- // to have a null owner. Instead, an owner change is pending when
372
- // this._owner !== this._pendingOwner.
373
- this._pendingOwner = this._owner;
374
-
375
- // Children can be more than one argument
376
- var childrenLength = arguments.length - 1;
377
- if (childrenLength === 1) {
378
- if ("production" !== process.env.NODE_ENV) {
379
- validateChildKeys(children);
380
- }
381
- this.props.children = children;
382
- } else if (childrenLength > 1) {
383
- var childArray = Array(childrenLength);
384
- for (var i = 0; i < childrenLength; i++) {
385
- if ("production" !== process.env.NODE_ENV) {
386
- validateChildKeys(arguments[i + 1]);
387
- }
388
- childArray[i] = arguments[i + 1];
389
- }
390
- this.props.children = childArray;
391
- }
234
+ // We keep the old descriptor and a reference to the pending descriptor
235
+ // to track updates.
236
+ this._descriptor = descriptor;
237
+ this._pendingDescriptor = null;
392
238
  },
393
239
 
394
240
  /**
@@ -413,9 +259,10 @@ var ReactComponent = {
413
259
  'single component instance in multiple places.',
414
260
  rootID
415
261
  ) : invariant(!this.isMounted()));
416
- var props = this.props;
262
+ var props = this._descriptor.props;
417
263
  if (props.ref != null) {
418
- ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
264
+ var owner = this._descriptor._owner;
265
+ ReactOwner.addComponentAsRefTo(this, props.ref, owner);
419
266
  }
420
267
  this._rootNodeID = rootID;
421
268
  this._lifeCycleState = ComponentLifeCycle.MOUNTED;
@@ -458,66 +305,70 @@ var ReactComponent = {
458
305
  * @param {ReactReconcileTransaction} transaction
459
306
  * @internal
460
307
  */
461
- receiveComponent: function(nextComponent, transaction) {
308
+ receiveComponent: function(nextDescriptor, transaction) {
462
309
  ("production" !== process.env.NODE_ENV ? invariant(
463
310
  this.isMounted(),
464
311
  'receiveComponent(...): Can only update a mounted component.'
465
312
  ) : invariant(this.isMounted()));
466
- this._pendingOwner = nextComponent._owner;
467
- this._pendingProps = nextComponent.props;
468
- this._performUpdateIfNecessary(transaction);
313
+ this._pendingDescriptor = nextDescriptor;
314
+ this.performUpdateIfNecessary(transaction);
469
315
  },
470
316
 
471
317
  /**
472
- * Call `_performUpdateIfNecessary` within a new transaction.
473
- *
474
- * @internal
475
- */
476
- performUpdateIfNecessary: function() {
477
- var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
478
- transaction.perform(this._performUpdateIfNecessary, this, transaction);
479
- ReactComponent.ReactReconcileTransaction.release(transaction);
480
- },
481
-
482
- /**
483
- * If `_pendingProps` is set, update the component.
318
+ * If `_pendingDescriptor` is set, update the component.
484
319
  *
485
320
  * @param {ReactReconcileTransaction} transaction
486
321
  * @internal
487
322
  */
488
- _performUpdateIfNecessary: function(transaction) {
489
- if (this._pendingProps == null) {
323
+ performUpdateIfNecessary: function(transaction) {
324
+ if (this._pendingDescriptor == null) {
490
325
  return;
491
326
  }
492
- var prevProps = this.props;
493
- var prevOwner = this._owner;
494
- this.props = this._pendingProps;
495
- this._owner = this._pendingOwner;
496
- this._pendingProps = null;
497
- this.updateComponent(transaction, prevProps, prevOwner);
327
+ var prevDescriptor = this._descriptor;
328
+ var nextDescriptor = this._pendingDescriptor;
329
+ this._descriptor = nextDescriptor;
330
+ this.props = nextDescriptor.props;
331
+ this._owner = nextDescriptor._owner;
332
+ this._pendingDescriptor = null;
333
+ this.updateComponent(transaction, prevDescriptor);
498
334
  },
499
335
 
500
336
  /**
501
337
  * Updates the component's currently mounted representation.
502
338
  *
503
339
  * @param {ReactReconcileTransaction} transaction
504
- * @param {object} prevProps
340
+ * @param {object} prevDescriptor
505
341
  * @internal
506
342
  */
507
- updateComponent: function(transaction, prevProps, prevOwner) {
508
- var props = this.props;
343
+ updateComponent: function(transaction, prevDescriptor) {
344
+ var nextDescriptor = this._descriptor;
345
+
509
346
  // If either the owner or a `ref` has changed, make sure the newest owner
510
347
  // has stored a reference to `this`, and the previous owner (if different)
511
- // has forgotten the reference to `this`.
512
- if (this._owner !== prevOwner || props.ref !== prevProps.ref) {
513
- if (prevProps.ref != null) {
348
+ // has forgotten the reference to `this`. We use the descriptor instead
349
+ // of the public this.props because the post processing cannot determine
350
+ // a ref. The ref conceptually lives on the descriptor.
351
+
352
+ // TODO: Should this even be possible? The owner cannot change because
353
+ // it's forbidden by shouldUpdateReactComponent. The ref can change
354
+ // if you swap the keys of but not the refs. Reconsider where this check
355
+ // is made. It probably belongs where the key checking and
356
+ // instantiateReactComponent is done.
357
+
358
+ if (nextDescriptor._owner !== prevDescriptor._owner ||
359
+ nextDescriptor.props.ref !== prevDescriptor.props.ref) {
360
+ if (prevDescriptor.props.ref != null) {
514
361
  ReactOwner.removeComponentAsRefFrom(
515
- this, prevProps.ref, prevOwner
362
+ this, prevDescriptor.props.ref, prevDescriptor._owner
516
363
  );
517
364
  }
518
365
  // Correct, even if the owner is the same, and only the ref has changed.
519
- if (props.ref != null) {
520
- ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
366
+ if (nextDescriptor.props.ref != null) {
367
+ ReactOwner.addComponentAsRefTo(
368
+ this,
369
+ nextDescriptor.props.ref,
370
+ nextDescriptor._owner
371
+ );
521
372
  }
522
373
  }
523
374
  },
@@ -533,7 +384,7 @@ var ReactComponent = {
533
384
  * @see {ReactMount.renderComponent}
534
385
  */
535
386
  mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
536
- var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
387
+ var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
537
388
  transaction.perform(
538
389
  this._mountComponentIntoNode,
539
390
  this,
@@ -542,7 +393,7 @@ var ReactComponent = {
542
393
  transaction,
543
394
  shouldReuseMarkup
544
395
  );
545
- ReactComponent.ReactReconcileTransaction.release(transaction);
396
+ ReactUpdates.ReactReconcileTransaction.release(transaction);
546
397
  },
547
398
 
548
399
  /**