diff --git a/src/diff/children.js b/src/diff/children.js index 63b61e045a..42cd334828 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -239,6 +239,7 @@ function constructNewChildrenArray( remainingOldChildren )); + oldVNode = NULL; if (matchingIndex != -1) { oldVNode = oldChildren[matchingIndex]; remainingOldChildren--; diff --git a/test/browser/keys.test.jsx b/test/browser/keys.test.jsx index 3550352242..9702781d51 100644 --- a/test/browser/keys.test.jsx +++ b/test/browser/keys.test.jsx @@ -179,9 +179,11 @@ describe('keys', () => { render({ children, busy }) { return (
- {children && children.length - ? children - :
} + {children && children.length ? ( + children + ) : ( +
+ )}
indicator
indicator
@@ -566,19 +568,21 @@ describe('keys', () => { let Stateful2MovedRef; function Foo({ moved }) { - return moved - ?
-
1
- (Stateful1MovedRef = c)} /> -
2
- (Stateful2MovedRef = c)} /> -
- :
-
1
- (Stateful1Ref = c)} /> -
2
- (Stateful2Ref = c)} /> -
; + return moved ? ( +
+
1
+ (Stateful1MovedRef = c)} /> +
2
+ (Stateful2MovedRef = c)} /> +
+ ) : ( +
+
1
+ (Stateful1Ref = c)} /> +
2
+ (Stateful2Ref = c)} /> +
+ ); } const expectedHtml = div([ @@ -635,31 +639,27 @@ describe('keys', () => { let Stateful2MovedRef; function Foo({ moved }) { - return moved - ?
-
1
- (c ? (Stateful2MovedRef = c) : undefined)} - /> -
2
- (c ? (Stateful1MovedRef = c) : undefined)} - /> -
- :
-
1
- (c ? (Stateful1Ref = c) : undefined)} - /> -
2
- (c ? (Stateful2Ref = c) : undefined)} - /> -
; + return moved ? ( +
+
1
+ (c ? (Stateful2MovedRef = c) : undefined)} + /> +
2
+ (c ? (Stateful1MovedRef = c) : undefined)} + /> +
+ ) : ( +
+
1
+ (c ? (Stateful1Ref = c) : undefined)} /> +
2
+ (c ? (Stateful2Ref = c) : undefined)} /> +
+ ); } const htmlForFalse = div([ @@ -841,19 +841,21 @@ describe('keys', () => { let Stateful2MovedRef; function Foo({ unkeyed }) { - return unkeyed - ?
-
1
- (Stateful2MovedRef = c)} /> -
2
- (Stateful1MovedRef = c)} /> -
- :
-
1
- (Stateful1Ref = c)} /> -
2
- (Stateful2Ref = c)} /> -
; + return unkeyed ? ( +
+
1
+ (Stateful2MovedRef = c)} /> +
2
+ (Stateful1MovedRef = c)} /> +
+ ) : ( +
+
1
+ (Stateful1Ref = c)} /> +
2
+ (Stateful2Ref = c)} /> +
+ ); } const expectedHtml = div([ @@ -1007,18 +1009,20 @@ describe('keys', () => { } const App = props => { - return props.y === '2' - ?
- - - -
- :
- {null} - - - -
; + return props.y === '2' ? ( +
+ + + +
+ ) : ( +
+ {null} + + + +
+ ); }; render(, scratch); @@ -1040,17 +1044,19 @@ describe('keys', () => { } const App = props => { - return props.y === '1' - ?
- - - -
- :
- - {null} - -
; + return props.y === '1' ? ( +
+ + + +
+ ) : ( +
+ + {null} + +
+ ); }; render(, scratch); @@ -1080,18 +1086,20 @@ describe('keys', () => { } const App = props => { - return props.y === '2' - ?
- - - -
- :
- - - {null} - -
; + return props.y === '2' ? ( +
+ + + +
+ ) : ( +
+ + + {null} + +
+ ); }; render(, scratch); @@ -1113,18 +1121,20 @@ describe('keys', () => { } const App = props => { - return props.y === '2' - ?
- - - -
- :
- - - - {null} -
; + return props.y === '2' ? ( +
+ + + +
+ ) : ( +
+ + + + {null} +
+ ); }; render(, scratch); @@ -1133,4 +1143,27 @@ describe('keys', () => { render(, scratch); expect(actions).to.deep.equal(['mounted 1', 'mounted 2', 'mounted 3']); }); + + // Issue #4973: Test growing list diff + it('should correctly diff a growing list of keyed children', () => { + let values = [0, 1, 2, 3, 4]; + + render(, scratch); + expect(scratch.textContent).to.equal('01234'); + + values = [2, 3, 4, 5, 6]; + clearLog(); + + render(, scratch); + expect(scratch.textContent).to.equal('23456'); + + expect(getLog()).to.deep.equal([ + '
  • 0.remove()', + '
  • 1.remove()', + '
  • .appendChild(#text)', + '
      234.appendChild(
    1. 5)', + '
    2. .appendChild(#text)', + '
        2345.appendChild(
      1. 6)' + ]); + }); });