From 046dbea8bac830a86582cebcfd40c53ccf1868fb Mon Sep 17 00:00:00 2001 From: Yukimasa Funaoka Date: Thu, 7 Mar 2019 00:21:55 +0900 Subject: [PATCH 1/2] Fix: componentWillReceiveProps must be called before shouldComponentUpdate --- src/diff/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/diff/index.js b/src/diff/index.js index aa912b2b3e..f1bb364e72 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -100,13 +100,14 @@ export function diff(dom, parentDom, newVNode, oldVNode, context, isSvg, excessD if (c.componentDidMount!=null) mounts.push(c); } else { + if (newType.getDerivedStateFromProps==null && c._force==null && c.componentWillReceiveProps!=null) { + c.componentWillReceiveProps(newVNode.props, cctx); + } + if (!c._force && c.shouldComponentUpdate!=null && c.shouldComponentUpdate(newVNode.props, s, cctx)===false) { c._dirty = false; break outer; } - if (newType.getDerivedStateFromProps==null && c._force==null && c.componentWillReceiveProps!=null) { - c.componentWillReceiveProps(newVNode.props, cctx); - } if (c.componentWillUpdate!=null) { c.componentWillUpdate(newVNode.props, s, cctx); From d8f9172409c910ee23d78f5f17f4729e2b0637e5 Mon Sep 17 00:00:00 2001 From: Yukimasa Funaoka Date: Thu, 7 Mar 2019 01:07:33 +0900 Subject: [PATCH 2/2] add tests for componentWillReceiveProps --- test/browser/lifecycle.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/browser/lifecycle.test.js b/test/browser/lifecycle.test.js index 64ea995715..bad8bda237 100644 --- a/test/browser/lifecycle.test.js +++ b/test/browser/lifecycle.test.js @@ -1008,6 +1008,11 @@ describe('Lifecycle methods', () => { expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; expect(Inner.prototype.componentDidUpdate).not.to.have.been.called; } + shouldComponentUpdate() { + expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; + expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; + return true; + } render() { return
; } @@ -1015,6 +1020,7 @@ describe('Lifecycle methods', () => { sinon.spy(Inner.prototype, 'componentWillReceiveProps'); sinon.spy(Inner.prototype, 'componentDidUpdate'); sinon.spy(Inner.prototype, 'componentWillUpdate'); + sinon.spy(Inner.prototype, 'shouldComponentUpdate'); sinon.spy(Outer.prototype, 'componentDidMount'); render(, scratch); @@ -1022,6 +1028,7 @@ describe('Lifecycle methods', () => { rerender(); expect(Inner.prototype.componentWillReceiveProps).to.have.been.calledBefore(Inner.prototype.componentWillUpdate); + expect(Inner.prototype.componentWillReceiveProps).to.have.been.calledBefore(Inner.prototype.shouldComponentUpdate); expect(Inner.prototype.componentWillUpdate).to.have.been.calledBefore(Inner.prototype.componentDidUpdate); }); });