From 2136889deb362bc66347fb5dcff2f95a6ec58302 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Fri, 12 Feb 2016 17:46:44 -0500 Subject: [PATCH] Fix an issue where nested components would not receive unmount lifecycle hooks (fixes Issue #47) --- src/vdom/component.js | 4 ++-- test/browser/render.js | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/vdom/component.js b/src/vdom/component.js index 919540ca59..ed7230983b 100644 --- a/src/vdom/component.js +++ b/src/vdom/component.js @@ -232,7 +232,7 @@ function createComponentFromVNode(vnode, dom, context) { function unmountComponent(dom, component, remove) { // console.warn('unmounting mismatched component', component); - hook(component, 'componentWillUnmount'); + deepHook(component, 'componentWillUnmount'); if (remove!==false) { if (dom._component===component) { delete dom._component; @@ -244,6 +244,6 @@ function unmountComponent(dom, component, remove) { } } component._parentComponent = null; - hook(component, 'componentDidUnmount'); + deepHook(component, 'componentDidUnmount'); collectComponent(component); } diff --git a/test/browser/render.js b/test/browser/render.js index 5bf15dd5fc..0686279b22 100644 --- a/test/browser/render.js +++ b/test/browser/render.js @@ -396,7 +396,9 @@ describe('render()', () => { }); it('should re-render nested components', () => { - let doRender = null; + let doRender = null, + alt = false; + class Outer extends Component { componentDidMount() { let i = 1; @@ -404,6 +406,7 @@ describe('render()', () => { } componentWillUnmount() {} render(props, { i }) { + if (alt) return
; return ; } } @@ -418,15 +421,19 @@ describe('render()', () => { this._constructor(...args); } _constructor() {} + componentWillMount() {} componentDidMount() {} componentWillUnmount() {} + componentDidUnmount() {} render(props) { return
inner
; } } sinon.spy(Inner.prototype, '_constructor'); sinon.spy(Inner.prototype, 'render'); + sinon.spy(Inner.prototype, 'componentWillMount'); sinon.spy(Inner.prototype, 'componentDidMount'); + sinon.spy(Inner.prototype, 'componentDidUnmount'); sinon.spy(Inner.prototype, 'componentWillUnmount'); render(, scratch); @@ -441,6 +448,8 @@ describe('render()', () => { expect(Inner.prototype._constructor).to.have.been.calledOnce; expect(Inner.prototype.componentWillUnmount).not.to.have.been.called; + expect(Inner.prototype.componentDidUnmount).not.to.have.been.called; + expect(Inner.prototype.componentWillMount).to.have.been.calledOnce; expect(Inner.prototype.componentDidMount).to.have.been.calledOnce; expect(Inner.prototype.render).to.have.been.calledTwice; @@ -461,6 +470,8 @@ describe('render()', () => { rerender(); expect(Inner.prototype.componentWillUnmount).not.to.have.been.called; + expect(Inner.prototype.componentDidUnmount).not.to.have.been.called; + expect(Inner.prototype.componentWillMount).to.have.been.calledOnce; expect(Inner.prototype.componentDidMount).to.have.been.calledOnce; expect(Inner.prototype.render).to.have.been.calledThrice; @@ -475,5 +486,14 @@ describe('render()', () => { })); expect(scratch.innerHTML).to.equal('
inner
'); + + + // update & flush + alt = true; + doRender(); + rerender(); + + expect(Inner.prototype.componentWillUnmount).to.have.been.calledOnce; + expect(Inner.prototype.componentDidUnmount).to.have.been.calledOnce; }); });