50
UNMOUNTED: null
51
});
52
53
+/**
54
+ * Warn if there's no key explicitly set on dynamic arrays of children.
55
+ * This allows us to keep track of children between updates.
56
+ */
57
+
58
+var CHILD_HAS_NO_IDENTITY =
59
+ 'You are passing a dynamic array of children. You should set the ' +
60
+ 'property "key" to a string that uniquely identifies each child.';
61
+
62
+var HAS_WARNED = false;
63
+
64
+/**
65
+ * Helpers for flattening child arguments onto a new array or use an existing
66
+ * one.
67
+ */
68
+
69
+function isEmptyChild(child) {
70
+ return child == null || typeof child === 'boolean';
71
+}
72
+
73
+function assignKey(setKey, child, index) {
74
+ if (ReactComponent.isValidComponent(child)) {
75
+ var key = child._key || child.props.key;
76
+ if (__DEV__) {
77
+ if (!HAS_WARNED && !key) {
78
+ HAS_WARNED = true;
79
+ console && console.warn && console.warn(CHILD_HAS_NO_IDENTITY);
80
+ }
81
+ }
82
+ child._key = (setKey ? setKey + ':' : '') + (key || ('' + index));
83
+ }
84
+}
85
+
86
+function tryToReuseArray(children) {
87
+ for (var i = 0; i < children.length; i++) {
88
+ var child = children[i];
89
+ if (isEmptyChild(child)) return false;
90
+ assignKey('', child, i);
91
+ }
92
+ return true;
93
+}
94
+
95
+function appendNestedChildren(parentKey, sourceArray, targetArray) {
96
+ for (var i = 0; i < sourceArray.length; i++) {
97
+ var child = sourceArray[i];
98
+ if (isEmptyChild(child)) continue;
99
+ assignKey(parentKey, child, i);
100
+ // TODO: Invalid components like strings could possibly need
101
+ // keys assigned to them here. Usually they're not stateful but
102
+ // CSS transitions and special events could make them stateful.
103
+ targetArray.push(child);
104
+ }
105
+}
106
+
107
/**
108
* Components are the basic units of composition in React.
109
*
260
*/
261
construct: function(initialProps, children) {
262
this.props = initialProps || {};
209
- if (typeof children !== 'undefined') {
210
- this.props.children = children;
211
- }
263
// Record the component responsible for creating this component.
264
this.props[OWNER] = ReactCurrentOwner.current;
265
// All components start unmounted.
266
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
267
+
268
+ // Children can be either an array or more than one argument
269
+ if (arguments.length < 2) {
270
+ return;
271
+ }
272
+
273
+ if (arguments.length === 2) {
274
+
275
+ // A single string or number child is treated as content, not an array.
276
+ var type = typeof children;
277
+ if (children == null || type === 'string' || type === 'number') {
278
+ this.props.children = children;
279
+ return;
280
+ }
281
+
282
+ // A single array can be reused if it's already flat
283
+ if (Array.isArray(children) && tryToReuseArray(children)) {
284
+ this.props.children = children;
285
+ return;
286
+ }
287
+
288
+ }
289
+
290
+ // Subsequent arguments are rolled into one child array. Array arguments
291
+ // are flattened onto it. This is inlined to avoid extra heap allocation.
292
+ var targetArray = null;
293
+ for (var i = 1; i < arguments.length; i++) {
294
+ var child = arguments[i];
295
+ if (Array.isArray(child)) {
296
+ if (child.length === 0) continue;
297
+
298
+ if (targetArray === null) targetArray = [];
299
+ appendNestedChildren(i - 1, child, targetArray);
300
+
301
+ } else if (!isEmptyChild(child)) {
302
+
303
+ if (ReactComponent.isValidComponent(child) && !child._key) {
304
+ // This is a static node and therefore safe to key by index.
305
+ // No warning necessary.
306
+ child._key = child.props.key || ('' + (i - 1));
307
+ }
308
+
309
+ if (targetArray === null) targetArray = [];
310
+ targetArray.push(child);
311
+
312
+ }
313
+ }
314
+ this.props.children = targetArray;
315
},
316
317
/**