Skip to content

Commit 6330171

Browse files
committed
Fix to call unexpected cDM
1 parent baaa2b5 commit 6330171

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4994,6 +4994,36 @@ describe('shallow', () => {
49944994
expect(spy).to.have.property('callCount', 1);
49954995
expect(wrapper.state('foo')).to.equal('update');
49964996
});
4997+
4998+
it('should not call `componentDidMount` twice when a child component is created', () => {
4999+
class Foo extends React.Component {
5000+
constructor(props) {
5001+
super(props);
5002+
this.state = {
5003+
foo: 'init',
5004+
};
5005+
}
5006+
5007+
componentDidMount() {}
5008+
5009+
render() {
5010+
return (
5011+
<div>
5012+
<button onClick={() => this.setState({foo: 'update2'})}>
5013+
click
5014+
</button>
5015+
{this.state.foo}
5016+
</div>
5017+
);
5018+
}
5019+
}
5020+
const spy = sinon.spy(Foo.prototype, 'componentDidMount');
5021+
5022+
const wrapper = shallow(<Foo />);
5023+
expect(spy).to.have.property('callCount', 1);
5024+
wrapper.find('button').prop('onClick')();
5025+
expect(spy).to.have.property('callCount', 1);
5026+
});
49975027
});
49985028

49995029
describeIf(is('>= 16'), 'support getSnapshotBeforeUpdate', () => {

packages/enzyme/src/ShallowWrapper.js

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -168,37 +168,38 @@ class ShallowWrapper {
168168
const adapter = getAdapter(options);
169169
const lifecycles = getAdapterLifecycles(adapter);
170170

171-
let renderedNode;
171+
// mounting a ShallowRender component
172172
if (!root) {
173173
privateSet(this, ROOT, this);
174174
privateSet(this, UNRENDERED, nodes);
175175
const renderer = adapter.createRenderer({ mode: 'shallow', ...options });
176176
privateSet(this, RENDERER, renderer);
177177
this[RENDERER].render(nodes, options.context);
178-
renderedNode = this[RENDERER].getNode();
178+
const renderedNode = this[RENDERER].getNode();
179179
privateSetNodes(this, getRootNode(renderedNode));
180+
privateSet(this, OPTIONS, options);
181+
182+
const { instance } = renderedNode;
183+
if (instance && !options.disableLifecycleMethods) {
184+
// Ensure to call componentDidUpdate when instance.setState is called
185+
if (lifecycles.componentDidUpdate.onSetState && !instance[SET_STATE]) {
186+
privateSet(instance, SET_STATE, instance.setState);
187+
instance.setState = (...args) => this.setState(...args);
188+
}
189+
190+
if (typeof instance.componentDidMount === 'function') {
191+
this[RENDERER].batchedUpdates(() => {
192+
instance.componentDidMount();
193+
});
194+
}
195+
}
196+
// creating a child component through enzyme's ShallowWrapper APIs.
180197
} else {
181198
privateSet(this, ROOT, root);
182199
privateSet(this, UNRENDERED, null);
183200
privateSet(this, RENDERER, root[RENDERER]);
184201
privateSetNodes(this, nodes);
185-
renderedNode = this[RENDERER].getNode();
186-
}
187-
privateSet(this, OPTIONS, root ? root[OPTIONS] : options);
188-
189-
const { instance } = renderedNode;
190-
if (instance && !options.disableLifecycleMethods) {
191-
// Ensure to call componentDidUpdate when instance.setState is called
192-
if (lifecycles.componentDidUpdate.onSetState && !instance[SET_STATE]) {
193-
privateSet(instance, SET_STATE, instance.setState);
194-
instance.setState = (...args) => this.setState(...args);
195-
}
196-
197-
if (typeof instance.componentDidMount === 'function') {
198-
this[RENDERER].batchedUpdates(() => {
199-
instance.componentDidMount();
200-
});
201-
}
202+
privateSet(this, OPTIONS, root[OPTIONS]);
202203
}
203204
}
204205

0 commit comments

Comments
 (0)