enzyme: componentDidUpdate is not called for shallow rendered component
npm package versions
enzyme: 3.2.0 enzyme-adapter-react-16: 1.1.1 react: 16.2.0 react-dom: 16.2.0
Problem
When changing the state inside a component, componentDidUpdate
is not called.
Expected behaviour
When changing the state inside a component, componentDidUpdate
should get called.
Code example
import { shallow } from 'enzyme';
import React from 'react';
class Dropdown extends React.Component {
constructor(props) {
super(props);
console.log('constructor');
this.state = {
highlightedIndex: 0,
};
this.handleMouseOver = this.handleMouseOver.bind(this);
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
handleMouseOver() {
console.log('handleMouseOver', 0);
this.setState({
highlightedIndex: 1,
}, () => {
console.log('handleMouseOver', 1);
});
console.log('handleMouseOver', 2);
}
render() {
console.log('render');
return <div onMouseOver={this.handleMouseOver}>Please hover me</div>;
}
}
it('should work', () => {
const wrapper = shallow(<Dropdown />);
wrapper.simulate('mouseover');
wrapper.update();
});
Console output
console.log .../__tests__/Dropdown.js:8
constructor
console.log .../__tests__/Dropdown.js:34
render
console.log .../__tests__/Dropdown.js:22
handleMouseOver 0
console.log .../__tests__/Dropdown.js:34
render
console.log .../__tests__/Dropdown.js:27
handleMouseOver 1
console.log .../__tests__/Dropdown.js:30
handleMouseOver 2
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 2
- Comments: 28 (17 by maintainers)
Commits related to this issue
- [Tests] `shallow`: add `componentDidUpdate` tests Per https://github.com/airbnb/enzyme/issues/1452#issuecomment-402421812 — committed to enzymejs/enzyme by koba04 6 years ago
- [Fix] `shallow`: call cDU when an instance calls setState stub instance.setState when the component is mounting Fixes #1452. — committed to koba04/enzyme by koba04 6 years ago
- [Tests] `shallow`: add `componentDidUpdate` tests Per https://github.com/airbnb/enzyme/issues/1452#issuecomment-402421812 — committed to enzymejs/enzyme by koba04 6 years ago
- [Tests] `shallow`: add `componentDidUpdate` tests Per https://github.com/airbnb/enzyme/issues/1452#issuecomment-402421812 — committed to enzymejs/enzyme by koba04 6 years ago
- [Tests] `shallow`: add `componentDidUpdate` tests Per https://github.com/airbnb/enzyme/issues/1452#issuecomment-402421812 — committed to web-developer77/react-enzyme by web-developer77 6 years ago
@koba04, using the same example as above, the way that I implemented it is this:
Please note that your new code should make this problem irrelevant.
The fix that I used was to split the test:
@ljharb Yes, that causes to rerender normally as ReactShallowRenderer, which means
componentDidUpdate
is never called because ReactShallowRenderer doesn’t support the lifecycle method. WhensetState
is called from ReactComponent instance directly, it is processed in the React ShallowRenderer so enzyme can’t handle the update to call the lifecycle method.Current lifecycle methods support is hooking update methods ShallowWrapper provides, which are
shallowWrapper.setState
orshallowWrapper.setProps
orshallow()
etc… So enzyme should be aware of that to do that.@koba04 you are right, the issue I saw was inside of render() after a wrapper.update(). I will investigate the details and file a separate issue if necessary.