componentDidUpdate() does not get called when .setProps() is called with new props
- Dominant language
- JavaScript
- Stars
- 19.8k
- Forks
- 2k
- PR merge metrics
- No merged PRs in 30d
Description
The [shallow docs](https://airbnb.io/enzyme/docs/api/shallow.html#shallow-rendering-api) explicitly indicate that the `componentDidUpdate` lifecycle method will get called by shallow mounted components, yet given the following test case this is not actually happening:
```
import { shallow } from 'enzyme';
import React from 'react';
import PropTypes from "prop-types";
import { isEqual } from 'lodash';
class Foo extends React.Component {
static propTypes = {
values: PropTypes.arrayOf(PropTypes.number).isRequired
};
static computeTotal(values) {
return values.reduce((total, value) => {
return total + value;
}, 0);
}
constructor(props) {
super(props);
this.state = {
totalValue: Foo.computeTotal(props.values)
};
}
componentDidUpdate(prevProps) {
const { values } = this.props;
const { values: oldValues } = prevProps;
if (!isEqual(values, oldValues)) {
this.setState({ totalValue: Foo.computeTotal(values) });
}
}
render() {
const { values } = this.props;
const { totalValue } = this.state;
return (
}
}
describe('Foo', () => {
let wrapper;
beforeAll(() => {
wrapper = shallow();
});
it('has the expected total', () => {
expect(wrapper.text()).toEqual('1 + 2 = 3');
});
it('changing values updates total', () => {
wrapper.setProps({ values: [2, 3] });
expect(wrapper.text()).toEqual('2 + 3 = 5');
});
});
```
### Current behavior
Foo
✓ has the expected total (7ms)
✕ changing values updates total (8ms)
● Foo › changing values updates total
expect(received).toEqual(expected) // deep equality
Expected: "2 + 3 = 5"
Received: "2 + 3 = 3"
48 | it('changing values updates total', () => {
49 | wrapper.setProps({ values: [2, 3] });
> 50 | expect(wrapper.text()).toEqual('2 + 3 = 5');
| ^
51 | });
52 | });
53 |
### Expected behavior
Both tests pass
### Your environment
node: 12.4.0
#### API
- [x] shallow
- [ ] mount
- [ ] render
#### Version
| library | version
| ------------------- | -------
| enzyme | 3.10.0
| react | 16.8.6
| react-dom | 16.8.6
| react-test-renderer | 16.8.6
| adapter (below) | 1.14.0
#### Adapter
- [x] enzyme-adapter-react-16
- [ ] enzyme-adapter-react-16.3
- [ ] enzyme-adapter-react-16.2
- [ ] enzyme-adapter-react-16.1
- [ ] enzyme-adapter-react-15
- [ ] enzyme-adapter-react-15.4
- [ ] enzyme-adapter-react-14
- [ ] enzyme-adapter-react-13
- [ ] enzyme-adapter-react-helper
- [ ] others ( )
Contributor guide
Research direction
Start with the shallow API documentation and reproduce the supplied Foo example using setProps() and componentDidUpdate(). Trace the shallow update path to determine why the lifecycle method does not update state, then verify that both shown expectations pass without changing mount or render behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100