From 3468ab40e069b735bc4a78d9201237f41203fed7 Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Sun, 26 Nov 2023 14:01:36 -0800 Subject: [PATCH 1/2] Fix access to undefined exception --- src/diff/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/diff/index.js b/src/diff/index.js index b5bbb49db6..6eede322f0 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -405,7 +405,10 @@ function diffElementNodes( if (isSvg) { dom = document.createElementNS('http://www.w3.org/2000/svg', nodeType); } else { - dom = document.createElement(nodeType, newProps.is && newProps); + dom = document.createElement( + nodeType, + newProps && newProps.is && newProps + ); } // we created a new parent, so none of the previously attached children can be reused: From 1870b9e02ba04a8820e3cc3a1ca3ba55d8fc5c94 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Mon, 27 Nov 2023 12:00:01 +0100 Subject: [PATCH 2/2] fix: invalid child vnodes throwing --- src/diff/children.js | 2 +- src/diff/index.js | 5 +---- test/browser/components.test.js | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/diff/children.js b/src/diff/children.js index 40a038722f..369014af39 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -212,7 +212,7 @@ function constructNewChildrenArray(newParentVNode, renderResult, oldChildren) { null, null ); - } else if (childVNode._depth > 0) { + } else if (childVNode.constructor === undefined && childVNode._depth > 0) { // VNode is already in use, clone it. This can happen in the following // scenario: // const reuse =
diff --git a/src/diff/index.js b/src/diff/index.js index 6eede322f0..b5bbb49db6 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -405,10 +405,7 @@ function diffElementNodes( if (isSvg) { dom = document.createElementNS('http://www.w3.org/2000/svg', nodeType); } else { - dom = document.createElement( - nodeType, - newProps && newProps.is && newProps - ); + dom = document.createElement(nodeType, newProps.is && newProps); } // we created a new parent, so none of the previously attached children can be reused: diff --git a/test/browser/components.test.js b/test/browser/components.test.js index 1dfb7a55d9..2c1a80c35d 100644 --- a/test/browser/components.test.js +++ b/test/browser/components.test.js @@ -1897,6 +1897,28 @@ describe('Components', () => { expect(unmounted).to.equal(',0,1,2,3'); }); + it('should ignore invalid vnodes in children array', () => { + /** @type { (() => void)} */ + let update; + + const obj = { a: 10, b: 'hello' }; + class App extends Component { + constructor(props) { + super(props); + this.state = { i: 0 }; + update = () => this.setState({ i: this.state.i + 1 }); + } + + render() { + return

{obj}

; + } + } + + render(, scratch); + update(); + expect(() => rerender()).not.to.throw(); + }); + describe('c.base', () => { /* eslint-disable lines-around-comment */ /** @type {import('../../src').Component} */