diff --git a/src/isomorphic/children/ReactChildren.js b/src/isomorphic/children/ReactChildren.js index 1e275b601c..da8848d229 100644 --- a/src/isomorphic/children/ReactChildren.js +++ b/src/isomorphic/children/ReactChildren.js @@ -117,8 +117,8 @@ function mapSingleChildIntoContext(bookKeeping, child, childKey) { // traverseAllChildren used to do for objects as children keyPrefix + ( - mappedChild !== child ? - escapeUserProvidedKey(mappedChild.key || '') + '/' : + (mappedChild.key && (!child || (child.key !== mappedChild.key))) ? + escapeUserProvidedKey(mappedChild.key) + '/' : '' ) + childKey diff --git a/src/isomorphic/children/__tests__/ReactChildren-test.js b/src/isomorphic/children/__tests__/ReactChildren-test.js index a85d9dbf0e..e638c68c10 100644 --- a/src/isomorphic/children/__tests__/ReactChildren-test.js +++ b/src/isomorphic/children/__tests__/ReactChildren-test.js @@ -85,7 +85,7 @@ describe('ReactChildren', function() { expect(ReactChildren.count(mappedChildren)).toBe(1); expect(mappedChildren[0]).not.toBe(simpleKid); expect(mappedChildren[0].props.children).toBe(simpleKid); - expect(mappedChildren[0].key).toBe('/.$simple'); + expect(mappedChildren[0].key).toBe('.$simple'); }); it('should invoke callback with the right context', function() { @@ -117,17 +117,15 @@ describe('ReactChildren', function() { var three = null; var four =
; - var zeroMapped = ; // Key should be joined to obj key - var oneMapped = null; // Key should be added even if we don't supply it! - var twoMapped = ; // Key should be added even if not supplied! - var threeMapped = ; // Map from null to something. - var fourMapped = ; - + var mapped = [ + , // Key should be joined to obj key + null, // Key should be added even if we don't supply it! + , // Key should be added even if not supplied! + , // Map from null to something. + , + ]; var callback = jasmine.createSpy().andCallFake(function(kid, index) { - return index === 0 ? zeroMapped : - index === 1 ? oneMapped : - index === 2 ? twoMapped : - index === 3 ? threeMapped : fourMapped; + return mapped[index]; }); var instance = ( @@ -159,7 +157,7 @@ describe('ReactChildren', function() { mappedChildren[2].key, mappedChildren[3].key, ]).toEqual( - ['giraffe/.$keyZero', '/.$keyTwo', '/.3', 'keyFour/.$keyFour'] + ['giraffe/.$keyZero', '.$keyTwo', '.3', '.$keyFour'] ); expect(callback).toHaveBeenCalledWith(zero, 0); @@ -169,9 +167,9 @@ describe('ReactChildren', function() { expect(callback).toHaveBeenCalledWith(four, 4); expect(mappedChildren[0]).toEqual(); - expect(mappedChildren[1]).toEqual(); - expect(mappedChildren[2]).toEqual(); - expect(mappedChildren[3]).toEqual(); + expect(mappedChildren[1]).toEqual(); + expect(mappedChildren[2]).toEqual(); + expect(mappedChildren[3]).toEqual(); }); it('should be called for each child in nested structure', function() { @@ -241,15 +239,15 @@ describe('ReactChildren', function() { mappedChildren[3].key, ]).toEqual([ 'giraffe/.0:$firstHalfKey/.$keyZero', - '/.0:$firstHalfKey/.$keyTwo', + '.0:$firstHalfKey/.$keyTwo', 'keyFour/.0:$secondHalfKey/.$keyFour', - '/.0:$keyFive/.$keyFiveInner', + '.0:$keyFive/.$keyFiveInner', ]); expect(mappedChildren[0]).toEqual(); - expect(mappedChildren[1]).toEqual(); + expect(mappedChildren[1]).toEqual(); expect(mappedChildren[2]).toEqual(); - expect(mappedChildren[3]).toEqual(); + expect(mappedChildren[3]).toEqual(); }); it('should retain key across two mappings', function() { @@ -272,7 +270,7 @@ describe('ReactChildren', function() { ); - var expectedForcedKeys = ['giraffe/.$keyZero', '/.$keyOne']; + var expectedForcedKeys = ['giraffe/.$keyZero', '.$keyOne']; var mappedChildrenForcedKeys = ReactChildren.map(forcedKeys.props.children, mapFn); var mappedForcedKeys = mappedChildrenForcedKeys.map((c) => c.key); @@ -280,7 +278,7 @@ describe('ReactChildren', function() { var expectedRemappedForcedKeys = [ 'giraffe/.$giraffe/.$keyZero', - '/.$/.$keyOne', + '.$.$keyOne', ]; var remappedChildrenForcedKeys = ReactChildren.map(mappedChildrenForcedKeys, mapFn); @@ -310,6 +308,46 @@ describe('ReactChildren', function() { }).not.toThrow(); }); + it('should use the same key for a cloned element', function() { + var instance = ( +