diff --git a/src/diff/children.js b/src/diff/children.js index ba2730478c..84d550e8ae 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -398,8 +398,9 @@ function findMatchingIndex( // if the oldVNode was null or matched, then there could needs to be at least // 1 (aka `remainingOldChildren > 0`) children to find and compare against. let shouldSearch = + (typeof type !== 'function' || type === Fragment || key) && remainingOldChildren > - (oldVNode != null && (oldVNode._flags & MATCHED) === 0 ? 1 : 0); + (oldVNode != null && (oldVNode._flags & MATCHED) === 0 ? 1 : 0); if ( oldVNode === null || diff --git a/test/browser/render.test.js b/test/browser/render.test.js index 96bef10bb0..39b0ad86ba 100644 --- a/test/browser/render.test.js +++ b/test/browser/render.test.js @@ -1786,6 +1786,37 @@ describe('render()', () => { ); }); + // #2949 + it('should not swap unkeyed chlildren', () => { + class X extends Component { + constructor(props) { + super(props); + this.name = props.name; + } + render() { + return
{this.name}
; + } + } + + function Foo({ condition }) { + return ( +