Skip to content

Commit

Permalink
fix: case where shrinking a list would cause an exception (#4312)
Browse files Browse the repository at this point in the history
* yikes

* fix issue
  • Loading branch information
JoviDeCroock authored Mar 19, 2024
1 parent a784a62 commit 342b50e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/diff/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ export function diffChildren(
childVNode._flags & INSERT_VNODE ||
oldVNode._children === childVNode._children
) {
if (!newDom && oldVNode._dom == oldDom) {
oldDom = getDomSibling(oldVNode);
}
oldDom = insert(childVNode, oldDom, parentDom);
} else if (
typeof childVNode.type == 'function' &&
Expand Down Expand Up @@ -241,6 +244,7 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) {
if (oldVNode._dom == newParentVNode._nextDom) {
newParentVNode._nextDom = getDomSibling(oldVNode);
}

unmount(oldVNode, oldVNode, false);

// Explicitly nullify this position in oldChildren instead of just
Expand Down
48 changes: 46 additions & 2 deletions test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1481,8 +1481,8 @@ describe('render()', () => {

expect(serializeHtml(scratch)).to.equal(
'<div><p>_B1</p><p>_B2</p><p>_B3</p><h2>_B4</h2><p>_B5</p><p>_B6</p><p>_B7</p><h2>_B8</h2><p>_B9</p><p>_B10</p><p>_B11</p><p>_B12</p><h2>_B13</h2></div>'
);
});
);
});

it('should not crash or repeatedly add the same child when replacing a matched vnode with null (mixed dom-types)', () => {
const B = () => <div>B</div>;
Expand Down Expand Up @@ -1537,4 +1537,48 @@ describe('render()', () => {
'<div><span>A</span><div>B</div><div>C</div></div>'
);
});

it('should shrink lists', () => {
function RenderedItem({ item }) {
if (item.renderAsNullInComponent) {
return null;
}

return <div>{item.id}</div>;
}

function App({ list }) {
return (
<div>
{list.map(item => (
<RenderedItem key={item.id} item={item} />
))}
</div>
);
}

const firstList = [
{ id: 'One' },
{ id: 'Two' },
{ id: 'Three' },
{ id: 'Four' }
];

const secondList = [
{ id: 'One' },
{ id: 'Four', renderAsNullInComponent: true },
{ id: 'Six' },
{ id: 'Seven' }
];

render(<App list={firstList} />, scratch);
expect(scratch.innerHTML).to.equal(
'<div><div>One</div><div>Two</div><div>Three</div><div>Four</div></div>'
);

render(<App list={secondList} />, scratch);
expect(scratch.innerHTML).to.equal(
'<div><div>One</div><div>Six</div><div>Seven</div></div>'
);
});
});

0 comments on commit 342b50e

Please sign in to comment.