From 6330171ef04c04fe297c429d93b298aa37a32b38 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Sat, 18 Aug 2018 00:51:57 +0900 Subject: [PATCH] Fix to call unexpected cDM --- .../test/ShallowWrapper-spec.jsx | 30 ++++++++++++++ packages/enzyme/src/ShallowWrapper.js | 39 ++++++++++--------- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 2745b9faa..4418fe35a 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -4994,6 +4994,36 @@ describe('shallow', () => { expect(spy).to.have.property('callCount', 1); expect(wrapper.state('foo')).to.equal('update'); }); + + it('should not call `componentDidMount` twice when a child component is created', () => { + class Foo extends React.Component { + constructor(props) { + super(props); + this.state = { + foo: 'init', + }; + } + + componentDidMount() {} + + render() { + return ( +
+ + {this.state.foo} +
+ ); + } + } + const spy = sinon.spy(Foo.prototype, 'componentDidMount'); + + const wrapper = shallow(); + expect(spy).to.have.property('callCount', 1); + wrapper.find('button').prop('onClick')(); + expect(spy).to.have.property('callCount', 1); + }); }); describeIf(is('>= 16'), 'support getSnapshotBeforeUpdate', () => { diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js index e7f774755..ff1c5e40b 100644 --- a/packages/enzyme/src/ShallowWrapper.js +++ b/packages/enzyme/src/ShallowWrapper.js @@ -168,37 +168,38 @@ class ShallowWrapper { const adapter = getAdapter(options); const lifecycles = getAdapterLifecycles(adapter); - let renderedNode; + // mounting a ShallowRender component if (!root) { privateSet(this, ROOT, this); privateSet(this, UNRENDERED, nodes); const renderer = adapter.createRenderer({ mode: 'shallow', ...options }); privateSet(this, RENDERER, renderer); this[RENDERER].render(nodes, options.context); - renderedNode = this[RENDERER].getNode(); + const renderedNode = this[RENDERER].getNode(); privateSetNodes(this, getRootNode(renderedNode)); + privateSet(this, OPTIONS, options); + + const { instance } = renderedNode; + if (instance && !options.disableLifecycleMethods) { + // Ensure to call componentDidUpdate when instance.setState is called + if (lifecycles.componentDidUpdate.onSetState && !instance[SET_STATE]) { + privateSet(instance, SET_STATE, instance.setState); + instance.setState = (...args) => this.setState(...args); + } + + if (typeof instance.componentDidMount === 'function') { + this[RENDERER].batchedUpdates(() => { + instance.componentDidMount(); + }); + } + } + // creating a child component through enzyme's ShallowWrapper APIs. } else { privateSet(this, ROOT, root); privateSet(this, UNRENDERED, null); privateSet(this, RENDERER, root[RENDERER]); privateSetNodes(this, nodes); - renderedNode = this[RENDERER].getNode(); - } - privateSet(this, OPTIONS, root ? root[OPTIONS] : options); - - const { instance } = renderedNode; - if (instance && !options.disableLifecycleMethods) { - // Ensure to call componentDidUpdate when instance.setState is called - if (lifecycles.componentDidUpdate.onSetState && !instance[SET_STATE]) { - privateSet(instance, SET_STATE, instance.setState); - instance.setState = (...args) => this.setState(...args); - } - - if (typeof instance.componentDidMount === 'function') { - this[RENDERER].batchedUpdates(() => { - instance.componentDidMount(); - }); - } + privateSet(this, OPTIONS, root[OPTIONS]); } }