Skip to content

Commit 5a02923

Browse files
authored
Forwardport diffign fix (#4976)
1 parent 0999ff4 commit 5a02923

File tree

2 files changed

+135
-101
lines changed

2 files changed

+135
-101
lines changed

src/diff/children.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ function constructNewChildrenArray(
239239
remainingOldChildren
240240
));
241241

242+
oldVNode = NULL;
242243
if (matchingIndex != -1) {
243244
oldVNode = oldChildren[matchingIndex];
244245
remainingOldChildren--;

test/browser/keys.test.jsx

Lines changed: 134 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,11 @@ describe('keys', () => {
179179
render({ children, busy }) {
180180
return (
181181
<div class={busy ? 'busy' : ''}>
182-
{children && children.length
183-
? children
184-
: <div class="busy-placeholder" />}
182+
{children && children.length ? (
183+
children
184+
) : (
185+
<div class="busy-placeholder" />
186+
)}
185187
<div class="indicator">
186188
<div>indicator</div>
187189
<div>indicator</div>
@@ -566,19 +568,21 @@ describe('keys', () => {
566568
let Stateful2MovedRef;
567569

568570
function Foo({ moved }) {
569-
return moved
570-
? <div>
571-
<div>1</div>
572-
<Stateful1 key="c" ref={c => (Stateful1MovedRef = c)} />
573-
<div>2</div>
574-
<Stateful2 key="d" ref={c => (Stateful2MovedRef = c)} />
575-
</div>
576-
: <div>
577-
<div>1</div>
578-
<Stateful1 key="a" ref={c => (Stateful1Ref = c)} />
579-
<div>2</div>
580-
<Stateful2 key="b" ref={c => (Stateful2Ref = c)} />
581-
</div>;
571+
return moved ? (
572+
<div>
573+
<div>1</div>
574+
<Stateful1 key="c" ref={c => (Stateful1MovedRef = c)} />
575+
<div>2</div>
576+
<Stateful2 key="d" ref={c => (Stateful2MovedRef = c)} />
577+
</div>
578+
) : (
579+
<div>
580+
<div>1</div>
581+
<Stateful1 key="a" ref={c => (Stateful1Ref = c)} />
582+
<div>2</div>
583+
<Stateful2 key="b" ref={c => (Stateful2Ref = c)} />
584+
</div>
585+
);
582586
}
583587

584588
const expectedHtml = div([
@@ -635,31 +639,27 @@ describe('keys', () => {
635639
let Stateful2MovedRef;
636640

637641
function Foo({ moved }) {
638-
return moved
639-
? <div>
640-
<div>1</div>
641-
<Stateful2
642-
key="b"
643-
ref={c => (c ? (Stateful2MovedRef = c) : undefined)}
644-
/>
645-
<div>2</div>
646-
<Stateful1
647-
key="a"
648-
ref={c => (c ? (Stateful1MovedRef = c) : undefined)}
649-
/>
650-
</div>
651-
: <div>
652-
<div>1</div>
653-
<Stateful1
654-
key="a"
655-
ref={c => (c ? (Stateful1Ref = c) : undefined)}
656-
/>
657-
<div>2</div>
658-
<Stateful2
659-
key="b"
660-
ref={c => (c ? (Stateful2Ref = c) : undefined)}
661-
/>
662-
</div>;
642+
return moved ? (
643+
<div>
644+
<div>1</div>
645+
<Stateful2
646+
key="b"
647+
ref={c => (c ? (Stateful2MovedRef = c) : undefined)}
648+
/>
649+
<div>2</div>
650+
<Stateful1
651+
key="a"
652+
ref={c => (c ? (Stateful1MovedRef = c) : undefined)}
653+
/>
654+
</div>
655+
) : (
656+
<div>
657+
<div>1</div>
658+
<Stateful1 key="a" ref={c => (c ? (Stateful1Ref = c) : undefined)} />
659+
<div>2</div>
660+
<Stateful2 key="b" ref={c => (c ? (Stateful2Ref = c) : undefined)} />
661+
</div>
662+
);
663663
}
664664

665665
const htmlForFalse = div([
@@ -841,19 +841,21 @@ describe('keys', () => {
841841
let Stateful2MovedRef;
842842

843843
function Foo({ unkeyed }) {
844-
return unkeyed
845-
? <div>
846-
<div>1</div>
847-
<Stateful1 ref={c => (Stateful2MovedRef = c)} />
848-
<div>2</div>
849-
<Stateful2 ref={c => (Stateful1MovedRef = c)} />
850-
</div>
851-
: <div>
852-
<div>1</div>
853-
<Stateful1 key="a" ref={c => (Stateful1Ref = c)} />
854-
<div>2</div>
855-
<Stateful2 key="b" ref={c => (Stateful2Ref = c)} />
856-
</div>;
844+
return unkeyed ? (
845+
<div>
846+
<div>1</div>
847+
<Stateful1 ref={c => (Stateful2MovedRef = c)} />
848+
<div>2</div>
849+
<Stateful2 ref={c => (Stateful1MovedRef = c)} />
850+
</div>
851+
) : (
852+
<div>
853+
<div>1</div>
854+
<Stateful1 key="a" ref={c => (Stateful1Ref = c)} />
855+
<div>2</div>
856+
<Stateful2 key="b" ref={c => (Stateful2Ref = c)} />
857+
</div>
858+
);
857859
}
858860

859861
const expectedHtml = div([
@@ -1007,18 +1009,20 @@ describe('keys', () => {
10071009
}
10081010

10091011
const App = props => {
1010-
return props.y === '2'
1011-
? <div>
1012-
<Comp key={1} i={1} />
1013-
<Comp key={2} i={2} />
1014-
<Comp key={3} i={3} />
1015-
</div>
1016-
: <div>
1017-
{null}
1018-
<Comp key={1} i={1} />
1019-
<Comp key={2} i={2} />
1020-
<Comp key={3} i={3} />
1021-
</div>;
1012+
return props.y === '2' ? (
1013+
<div>
1014+
<Comp key={1} i={1} />
1015+
<Comp key={2} i={2} />
1016+
<Comp key={3} i={3} />
1017+
</div>
1018+
) : (
1019+
<div>
1020+
{null}
1021+
<Comp key={1} i={1} />
1022+
<Comp key={2} i={2} />
1023+
<Comp key={3} i={3} />
1024+
</div>
1025+
);
10221026
};
10231027

10241028
render(<App y="1" />, scratch);
@@ -1040,17 +1044,19 @@ describe('keys', () => {
10401044
}
10411045

10421046
const App = props => {
1043-
return props.y === '1'
1044-
? <div>
1045-
<Comp key={1} i={1} />
1046-
<Comp key={2} i={2} />
1047-
<Comp key={3} i={3} />
1048-
</div>
1049-
: <div>
1050-
<Comp key={1} i={1} />
1051-
{null}
1052-
<Comp key={3} i={3} />
1053-
</div>;
1047+
return props.y === '1' ? (
1048+
<div>
1049+
<Comp key={1} i={1} />
1050+
<Comp key={2} i={2} />
1051+
<Comp key={3} i={3} />
1052+
</div>
1053+
) : (
1054+
<div>
1055+
<Comp key={1} i={1} />
1056+
{null}
1057+
<Comp key={3} i={3} />
1058+
</div>
1059+
);
10541060
};
10551061

10561062
render(<App y="1" />, scratch);
@@ -1080,18 +1086,20 @@ describe('keys', () => {
10801086
}
10811087

10821088
const App = props => {
1083-
return props.y === '2'
1084-
? <div>
1085-
<Comp key={1} i={1} />
1086-
<Comp key={2} i={2} />
1087-
<Comp key={3} i={3} />
1088-
</div>
1089-
: <div>
1090-
<Comp key={1} i={1} />
1091-
<Comp key={2} i={2} />
1092-
{null}
1093-
<Comp key={3} i={3} />
1094-
</div>;
1089+
return props.y === '2' ? (
1090+
<div>
1091+
<Comp key={1} i={1} />
1092+
<Comp key={2} i={2} />
1093+
<Comp key={3} i={3} />
1094+
</div>
1095+
) : (
1096+
<div>
1097+
<Comp key={1} i={1} />
1098+
<Comp key={2} i={2} />
1099+
{null}
1100+
<Comp key={3} i={3} />
1101+
</div>
1102+
);
10951103
};
10961104

10971105
render(<App y="1" />, scratch);
@@ -1113,18 +1121,20 @@ describe('keys', () => {
11131121
}
11141122

11151123
const App = props => {
1116-
return props.y === '2'
1117-
? <div>
1118-
<Comp key={1} i={1} />
1119-
<Comp key={2} i={2} />
1120-
<Comp key={3} i={3} />
1121-
</div>
1122-
: <div>
1123-
<Comp key={1} i={1} />
1124-
<Comp key={2} i={2} />
1125-
<Comp key={3} i={3} />
1126-
{null}
1127-
</div>;
1124+
return props.y === '2' ? (
1125+
<div>
1126+
<Comp key={1} i={1} />
1127+
<Comp key={2} i={2} />
1128+
<Comp key={3} i={3} />
1129+
</div>
1130+
) : (
1131+
<div>
1132+
<Comp key={1} i={1} />
1133+
<Comp key={2} i={2} />
1134+
<Comp key={3} i={3} />
1135+
{null}
1136+
</div>
1137+
);
11281138
};
11291139

11301140
render(<App y="1" />, scratch);
@@ -1133,4 +1143,27 @@ describe('keys', () => {
11331143
render(<App y="2" />, scratch);
11341144
expect(actions).to.deep.equal(['mounted 1', 'mounted 2', 'mounted 3']);
11351145
});
1146+
1147+
// Issue #4973: Test growing list diff
1148+
it('should correctly diff a growing list of keyed children', () => {
1149+
let values = [0, 1, 2, 3, 4];
1150+
1151+
render(<List values={values} />, scratch);
1152+
expect(scratch.textContent).to.equal('01234');
1153+
1154+
values = [2, 3, 4, 5, 6];
1155+
clearLog();
1156+
1157+
render(<List values={values} />, scratch);
1158+
expect(scratch.textContent).to.equal('23456');
1159+
1160+
expect(getLog()).to.deep.equal([
1161+
'<li>0.remove()',
1162+
'<li>1.remove()',
1163+
'<li>.appendChild(#text)',
1164+
'<ol>234.appendChild(<li>5)',
1165+
'<li>.appendChild(#text)',
1166+
'<ol>2345.appendChild(<li>6)'
1167+
]);
1168+
});
11361169
});

0 commit comments

Comments
 (0)