From d68462ce808910a6aa1edba70347679fe0f7843a Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 22 Sep 2022 11:34:31 +0200 Subject: [PATCH 1/5] create test case for #3742 --- .../lifecycles/componentDidUpdate.test.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/browser/lifecycles/componentDidUpdate.test.js b/test/browser/lifecycles/componentDidUpdate.test.js index 647adb8127..b3c7c860da 100644 --- a/test/browser/lifecycles/componentDidUpdate.test.js +++ b/test/browser/lifecycles/componentDidUpdate.test.js @@ -381,5 +381,54 @@ describe('Lifecycle methods', () => { expect(Inner.prototype.componentDidUpdate).to.have.been.called; expect(outerChildText).to.equal(`Outer: ${newValue.toString()}`); }); + + it('should not interfere with setState callbacks', () => { + let invocation; + + class Child extends Component { + componentDidMount() { + this.props.setValue(10); + } + render() { + return

Hello world

; + } + } + + class App extends Component { + constructor(props) { + super(props); + this.state = { + show: false, + count: null + }; + } + + componentDidMount() { + this.setState({ show: true }); + } + + componentDidUpdate() {} + + render() { + if (this.state.show) { + return ( + + this.setState({ count: i }, () => { + invocation = this.state; + }) + } + /> + ); + } + return null; + } + } + + render(, scratch); + + rerender(); + expect(invocation.count).to.equal(10); + }); }); }); From 0e46b386662cf6a6dcfb33637ab9569f87bd11a9 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 22 Sep 2022 13:04:26 +0200 Subject: [PATCH 2/5] solve issue --- src/component.js | 4 +++- src/diff/index.js | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/component.js b/src/component.js index cca3198eaf..f219acd7b5 100644 --- a/src/component.js +++ b/src/component.js @@ -47,7 +47,9 @@ Component.prototype.setState = function(update, callback) { if (update == null) return; if (this._vnode) { - if (callback) this._renderCallbacks.push(callback); + if (callback) { + this._stateCallbacks.push(callback); + } enqueueRender(this); } }; diff --git a/src/diff/index.js b/src/diff/index.js index e380895c29..0121e1fc1d 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -89,6 +89,7 @@ export function diff( c._globalContext = globalContext; isNew = c._dirty = true; c._renderCallbacks = []; + c._stateCallbacks = []; } // Invoke getDerivedStateFromProps @@ -109,6 +110,11 @@ export function diff( oldProps = c.props; oldState = c.state; + if (c._stateCallbacks.length) { + c._renderCallbacks.push(...c._stateCallbacks); + c._stateCallbacks = []; + } + // Invoke pre-render lifecycle methods if (isNew) { if ( From 1415dd4748efc21c5269fc6b6ae61e5c17311a3c Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 22 Sep 2022 13:05:26 +0200 Subject: [PATCH 3/5] types --- src/internal.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/internal.d.ts b/src/internal.d.ts index 25e2ed0c47..57faa0ded0 100644 --- a/src/internal.d.ts +++ b/src/internal.d.ts @@ -133,6 +133,7 @@ export interface Component

extends preact.Component { _dirty: boolean; _force?: boolean; _renderCallbacks: Array<() => void>; // Only class components + _stateCallbacks: Array<() => void>; // Only class components _globalContext?: any; _vnode?: VNode

| null; _nextState?: S | null; // Only class components From 84413309dd556e2114a7d2ac92e847ec3ba35ca8 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 22 Sep 2022 13:12:27 +0200 Subject: [PATCH 4/5] golf --- src/diff/index.js | 4 ++-- test/browser/lifecycles/componentDidUpdate.test.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/diff/index.js b/src/diff/index.js index 0121e1fc1d..fc564d3b20 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -110,8 +110,8 @@ export function diff( oldProps = c.props; oldState = c.state; - if (c._stateCallbacks.length) { - c._renderCallbacks.push(...c._stateCallbacks); + for (tmp = 0; tmp < c._stateCallbacks.length; tmp++) { + c._renderCallbacks.push(c._stateCallbacks[tmp]); c._stateCallbacks = []; } diff --git a/test/browser/lifecycles/componentDidUpdate.test.js b/test/browser/lifecycles/componentDidUpdate.test.js index b3c7c860da..41bae1bf50 100644 --- a/test/browser/lifecycles/componentDidUpdate.test.js +++ b/test/browser/lifecycles/componentDidUpdate.test.js @@ -404,6 +404,7 @@ describe('Lifecycle methods', () => { } componentDidMount() { + // eslint-disable-next-line this.setState({ show: true }); } From da77efe23f71e774490b22d56307998ba4ebbf9f Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 22 Sep 2022 15:23:04 +0200 Subject: [PATCH 5/5] add mangle --- mangle.json | 1 + 1 file changed, 1 insertion(+) diff --git a/mangle.json b/mangle.json index cf506a61e8..6633035754 100644 --- a/mangle.json +++ b/mangle.json @@ -44,6 +44,7 @@ "$_force": "__e", "$_nextState": "__s", "$_renderCallbacks": "__h", + "$_stateCallbacks": "_sb", "$_vnode": "__v", "$_children": "__k", "$_pendingSuspensionCount": "__u",