diff --git a/src/core/ReactComponent.js b/src/core/ReactComponent.js
index 5c42a8e86f..bc3769df92 100644
--- a/src/core/ReactComponent.js
+++ b/src/core/ReactComponent.js
@@ -72,7 +72,7 @@ function isEmptyChild(child) {
function assignKey(setKey, child, index) {
if (ReactComponent.isValidComponent(child)) {
- var key = child._key || child.props.key;
+ var key = child.props.key;
if (__DEV__) {
if (!HAS_WARNED && !key) {
HAS_WARNED = true;
@@ -300,7 +300,7 @@ var ReactComponent = {
} else if (!isEmptyChild(child)) {
- if (ReactComponent.isValidComponent(child) && !child._key) {
+ if (ReactComponent.isValidComponent(child)) {
// This is a static node and therefore safe to key by index.
// No warning necessary.
child._key = child.props.key || ('' + (i - 1));
diff --git a/src/core/__tests__/ReactIdentity-test.js b/src/core/__tests__/ReactIdentity-test.js
index ecf71a8553..e21be9d3bb 100644
--- a/src/core/__tests__/ReactIdentity-test.js
+++ b/src/core/__tests__/ReactIdentity-test.js
@@ -80,4 +80,75 @@ describe('ReactIdentity', function() {
.toEqual('.reactRoot[0].:2.:chipmunk');
});
+ it('should let restructured components retain their uniqueness', function() {
+ var instance0 = ;
+ var instance1 = ;
+ var instance2 = ;
+ var wrapped =
{instance0} {instance1}
;
+ var unwrappedAndAdded =
+
+ {instance2}
+ {wrapped.props.children[0]}
+ {wrapped.props.children[1]}
+
;
+
+ expect(function() {
+
+ React.renderComponent(unwrappedAndAdded, document.createElement('div'));
+
+ }).not.toThrow();
+ });
+
+ it('should retain keys during updates in composite components', function() {
+
+ var TestComponent = React.createClass({
+ render: function() {
+ return {this.props.children}
;
+ }
+ });
+
+ var TestContainer = React.createClass({
+
+ getInitialState: function() {
+ return { swapped: false };
+ },
+
+ swap: function() {
+ this.setState({ swapped: true });
+ },
+
+ render: function() {
+ return (
+
+ {this.state.swapped ? this.props.second : this.props.first}
+ {this.state.swapped ? this.props.first : this.props.second}
+
+ );
+ }
+
+ });
+
+ var instance0 = ;
+ var instance1 = ;
+
+ var wrapped = ;
+
+ React.renderComponent(wrapped, document.createElement('div'));
+
+ var beforeKey = wrapped
+ ._renderedComponent
+ ._renderedComponent
+ .props.children[0]._key;
+
+ wrapped.swap();
+
+ var afterKey = wrapped
+ ._renderedComponent
+ ._renderedComponent
+ .props.children[0]._key;
+
+ expect(beforeKey).not.toEqual(afterKey);
+
+ });
+
});
diff --git a/src/utils/mapChildren.js b/src/utils/mapChildren.js
index cdba3e4d90..27079e8930 100644
--- a/src/utils/mapChildren.js
+++ b/src/utils/mapChildren.js
@@ -26,7 +26,7 @@ function mapChildren(children, mapFunction, context) {
var child = children[ii];
var key = child._key;
var mappedChild = mapFunction.call(context, child, key, ii);
- mappedChild._key = key;
+ mappedChild.props.key = key;
mappedChildren.push(mappedChild);
}
return mappedChildren;