diff --git a/src/browser/server/__tests__/ReactServerRendering-test.js b/src/browser/server/__tests__/ReactServerRendering-test.js
index 6af97d250216b..1d1abb2970239 100644
--- a/src/browser/server/__tests__/ReactServerRendering-test.js
+++ b/src/browser/server/__tests__/ReactServerRendering-test.js
@@ -97,8 +97,7 @@ describe('ReactServerRendering', function() {
'
' +
'' +
- 'My name is ' +
- 'child' +
+ 'My name is child' +
'' +
'
'
);
@@ -146,8 +145,7 @@ describe('ReactServerRendering', function() {
expect(response).toMatch(
'' +
- 'Component name: ' +
- 'TestComponent' +
+ 'Component name: TestComponent' +
''
);
expect(lifecycle).toEqual(
diff --git a/src/core/__tests__/ReactMultiChildText-test.js b/src/core/__tests__/ReactMultiChildText-test.js
index d77c697409c2c..7099a8db68d6b 100644
--- a/src/core/__tests__/ReactMultiChildText-test.js
+++ b/src/core/__tests__/ReactMultiChildText-test.js
@@ -128,31 +128,31 @@ describe('ReactMultiChildText', function() {
// two adjacent values
[true, 0], ['0'],
- [0, 0], ['0', '0'],
- [1.2, 0], ['1.2', '0'],
- [0, ''], ['0', ''],
- ['foo', 0], ['foo', '0'],
+ [0, 0], ['00'],
+ [1.2, 0], ['1.20'],
+ [0, ''], ['0'],
+ ['foo', 0], ['foo0'],
[0, ], ['0', ],
[true, 1.2], ['1.2'],
- [1.2, 0], ['1.2', '0'],
- [1.2, 1.2], ['1.2', '1.2'],
- [1.2, ''], ['1.2', ''],
- ['foo', 1.2], ['foo', '1.2'],
+ [1.2, 0], ['1.20'],
+ [1.2, 1.2], ['1.21.2'],
+ [1.2, ''], ['1.2'],
+ ['foo', 1.2], ['foo1.2'],
[1.2, ], ['1.2', ],
[true, ''], [''],
- ['', 0], ['', '0'],
- [1.2, ''], ['1.2', ''],
- ['', ''], ['', ''],
- ['foo', ''], ['foo', ''],
+ ['', 0], ['0'],
+ [1.2, ''], ['1.2'],
+ ['', ''], [''],
+ ['foo', ''], ['foo'],
['', ], ['', ],
[true, 'foo'], ['foo'],
- ['foo', 0], ['foo', '0'],
- [1.2, 'foo'], ['1.2', 'foo'],
- ['foo', ''], ['foo', ''],
- ['foo', 'foo'], ['foo', 'foo'],
+ ['foo', 0], ['foo0'],
+ [1.2, 'foo'], ['1.2foo'],
+ ['foo', ''], ['foo'],
+ ['foo', 'foo'], ['foofoo'],
['foo', ], ['foo', ],
// values separated by an element
@@ -161,48 +161,48 @@ describe('ReactMultiChildText', function() {
['', , ''], ['', , ''],
['foo', , 'foo'], ['foo', , 'foo'],
- [true, 1.2, , '', 'foo'], ['1.2', , '', 'foo'],
- [1.2, '', , 'foo', true], ['1.2', '', , 'foo'],
- ['', 'foo', , true, 1.2], ['', 'foo', , '1.2'],
+ [true, 1.2, , '', 'foo'], ['1.2', , 'foo'],
+ [1.2, '', , 'foo', true], ['1.2', , 'foo'],
+ ['', 'foo', , true, 1.2], ['foo', , '1.2'],
- [true, 1.2, '', , 'foo', true, 1.2], ['1.2', '', , 'foo', '1.2'],
- ['', 'foo', true, , 1.2, '', 'foo'], ['', 'foo', , '1.2', '', 'foo'],
+ [true, 1.2, '', , 'foo', true, 1.2], ['1.2', , 'foo1.2'],
+ ['', 'foo', true, , 1.2, '', 'foo'], ['foo', , '1.2foo'],
// values inside arrays
[[true], [true]], [],
- [[1.2], [1.2]], ['1.2', '1.2'],
- [[''], ['']], ['', ''],
- [['foo'], ['foo']], ['foo', 'foo'],
+ [[1.2], [1.2]], ['1.21.2'],
+ [[''], ['']], [''],
+ [['foo'], ['foo']], ['foofoo'],
[[], []], [, ],
- [[true, 1.2, ], '', 'foo'], ['1.2', , '', 'foo'],
- [1.2, '', [, 'foo', true]], ['1.2', '', , 'foo'],
- ['', ['foo', , true], 1.2], ['', 'foo', , '1.2'],
+ [[true, 1.2, ], '', 'foo'], ['1.2', , 'foo'],
+ [1.2, '', [, 'foo', true]], ['1.2', , 'foo'],
+ ['', ['foo', , true], 1.2], ['foo', , '1.2'],
- [true, [1.2, '', , 'foo'], true, 1.2], ['1.2', '', , 'foo', '1.2'],
- ['', 'foo', [true, , 1.2, ''], 'foo'], ['', 'foo', , '1.2', '', 'foo'],
+ [true, [1.2, '', , 'foo'], true, 1.2], ['1.2', , 'foo1.2'],
+ ['', 'foo', [true, , 1.2, ''], 'foo'], ['foo', , '1.2foo'],
// values inside objects
[{a: true}, {a: true}], [],
- [{a: 1.2}, {a: 1.2}], ['1.2', '1.2'],
- [{a: ''}, {a: ''}], ['', ''],
- [{a: 'foo'}, {a: 'foo'}], ['foo', 'foo'],
+ [{a: 1.2}, {a: 1.2}], ['1.21.2'],
+ [{a: ''}, {a: ''}], [''],
+ [{a: 'foo'}, {a: 'foo'}], ['foofoo'],
[{a: }, {a: }], [, ],
- [{a: true, b: 1.2, c: }, '', 'foo'], ['1.2', , '', 'foo'],
- [1.2, '', {a: , b: 'foo', c: true}], ['1.2', '', , 'foo'],
- ['', {a: 'foo', b: , c: true}, 1.2], ['', 'foo', , '1.2'],
+ [{a: true, b: 1.2, c: }, '', 'foo'], ['1.2', , 'foo'],
+ [1.2, '', {a: , b: 'foo', c: true}], ['1.2', , 'foo'],
+ ['', {a: 'foo', b: , c: true}, 1.2], ['foo', , '1.2'],
- [true, {a: 1.2, b: '', c: , d: 'foo'}, true, 1.2], ['1.2', '', , 'foo', '1.2'],
- ['', 'foo', {a: true, b: , c: 1.2, d: ''}, 'foo'], ['', 'foo', , '1.2', '', 'foo'],
+ [true, {a: 1.2, b: '', c: , d: 'foo'}, true, 1.2], ['1.2', , 'foo1.2'],
+ ['', 'foo', {a: true, b: , c: 1.2, d: ''}, 'foo'], ['foo', , '1.2foo'],
// values inside elements
- [, '', 'foo'], [, '', 'foo'],
- [1.2, '', ], ['1.2', '', ],
+ [, '', 'foo'], [, 'foo'],
+ [1.2, '', ], ['1.2', ],
['', , 1.2], ['', , '1.2'],
[true, , true, 1.2], [, '1.2'],
- ['', 'foo', , 'foo'], ['', 'foo', , 'foo']
+ ['', 'foo', , 'foo'], ['foo', , 'foo']
]);
});
diff --git a/src/utils/flattenChildren.js b/src/utils/flattenChildren.js
index fe1a68cd6e0c0..19161b82021e4 100644
--- a/src/utils/flattenChildren.js
+++ b/src/utils/flattenChildren.js
@@ -18,9 +18,13 @@
"use strict";
+var ReactTextComponent = require('ReactTextComponent');
+
var traverseAllChildren = require('traverseAllChildren');
var warning = require('warning');
+var previousName = null;
+
/**
* @param {function} traverseContext Context passed through traversal.
* @param {?ReactComponent} child React child component.
@@ -38,7 +42,23 @@ function flattenSingleChildIntoContext(traverseContext, child, name) {
name
);
if (keyUnique && child != null) {
- result[name] = child;
+ var type = typeof child;
+ var normalizedValue;
+
+ if (type === 'string' || type === 'number') {
+ var previousValue = result[previousName];
+ if (previousValue && previousValue.type === ReactTextComponent.type) {
+ normalizedValue = ReactTextComponent(previousValue.props + child);
+ name = previousName;
+ } else {
+ normalizedValue = ReactTextComponent('' + child);
+ }
+ } else {
+ normalizedValue = child;
+ }
+
+ result[name] = normalizedValue;
+ previousName = name;
}
}
@@ -53,6 +73,7 @@ function flattenChildren(children) {
}
var result = {};
traverseAllChildren(children, flattenSingleChildIntoContext, result);
+ previousName = null;
return result;
}
diff --git a/src/utils/traverseAllChildren.js b/src/utils/traverseAllChildren.js
index 07e41b359dec7..773d570854aca 100644
--- a/src/utils/traverseAllChildren.js
+++ b/src/utils/traverseAllChildren.js
@@ -127,39 +127,32 @@ var traverseAllChildrenImpl =
// All of the above are perceived as null.
callback(traverseContext, null, storageName, indexSoFar);
subtreeCount = 1;
- } else if (ReactDescriptor.isValidDescriptor(children)) {
+ } else if (type === 'string' || type === 'number' ||
+ ReactDescriptor.isValidDescriptor(children)) {
callback(traverseContext, children, storageName, indexSoFar);
subtreeCount = 1;
- } else {
- if (type === 'object') {
- invariant(
- !children || children.nodeType !== 1,
- 'traverseAllChildren(...): Encountered an invalid child; DOM ' +
- 'elements are not valid children of React components.'
- );
- for (var key in children) {
- if (children.hasOwnProperty(key)) {
- subtreeCount += traverseAllChildrenImpl(
- children[key],
- (
- nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
- wrapUserProvidedKey(key) + SUBSEPARATOR +
- getComponentKey(children[key], 0)
- ),
- indexSoFar + subtreeCount,
- callback,
- traverseContext
- );
- }
+ } else if (type === 'object') {
+ invariant(
+ !children || children.nodeType !== 1,
+ 'traverseAllChildren(...): Encountered an invalid child; DOM ' +
+ 'elements are not valid children of React components.'
+ );
+ for (var key in children) {
+ if (children.hasOwnProperty(key)) {
+ var nextName = (
+ nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
+ wrapUserProvidedKey(key) + SUBSEPARATOR +
+ getComponentKey(children[key], 0)
+ );
+ var nextIndex = indexSoFar + subtreeCount;
+ subtreeCount += traverseAllChildrenImpl(
+ children[key],
+ nextName,
+ nextIndex,
+ callback,
+ traverseContext
+ );
}
- } else if (type === 'string') {
- var normalizedText = ReactTextComponent(children);
- callback(traverseContext, normalizedText, storageName, indexSoFar);
- subtreeCount += 1;
- } else if (type === 'number') {
- var normalizedNumber = ReactTextComponent('' + children);
- callback(traverseContext, normalizedNumber, storageName, indexSoFar);
- subtreeCount += 1;
}
}
}