Skip to content

Commit 9fe24eb

Browse files
committed
Fall back to insertBefore when the moved node was detached externally
1 parent e9415cf commit 9fe24eb

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/diff/children.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ function insert(parentVNode, oldDom, parentDom, isMounting) {
405405
oldDom = getDomSibling(parentVNode);
406406
}
407407

408-
if (HAS_MOVE_BEFORE_SUPPORT && !isMounting) {
408+
if (HAS_MOVE_BEFORE_SUPPORT && !isMounting && parentVNode._dom.parentNode) {
409409
// @ts-expect-error This isn't added to TypeScript lib.d.ts yet
410410
parentDom.moveBefore(parentVNode._dom, oldDom);
411411
} else {

test/browser/keys.test.jsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,4 +1553,34 @@ describe('keys', () => {
15531553
);
15541554
expect(scratch.querySelector('ul').textContent).to.equal('123');
15551555
});
1556+
1557+
it('should reorder keyed children after a third party removed one of them', () => {
1558+
let update;
1559+
class List extends Component {
1560+
constructor(props) {
1561+
super(props);
1562+
this.state = { order: [1, 2, 3] };
1563+
update = order => this.setState({ order });
1564+
}
1565+
render() {
1566+
return (
1567+
<ul>
1568+
{this.state.order.map(i => (
1569+
<li key={i}>{i}</li>
1570+
))}
1571+
</ul>
1572+
);
1573+
}
1574+
}
1575+
1576+
render(<List />, scratch);
1577+
// e.g. an ad blocker or a drag-and-drop library detaching the node
1578+
scratch.querySelector('li:nth-child(3)').remove();
1579+
1580+
update([3, 1, 2]);
1581+
rerender();
1582+
expect(scratch.innerHTML).to.equal(
1583+
'<ul><li>3</li><li>1</li><li>2</li></ul>'
1584+
);
1585+
});
15561586
});

0 commit comments

Comments
 (0)