diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js index 3134f991eea..0c1f7178831 100644 --- a/packages/react-test-renderer/src/ReactShallowRenderer.js +++ b/packages/react-test-renderer/src/ReactShallowRenderer.js @@ -238,14 +238,14 @@ class ReactShallowRenderer { const {type} = this._element; if (typeof type.getDerivedStateFromProps === 'function') { + const oldState = this._newState || this._instance.state; const partialState = type.getDerivedStateFromProps.call( null, props, - this._instance.state, + oldState, ); if (partialState != null) { - const oldState = this._newState || this._instance.state; const newState = Object.assign({}, oldState, partialState); this._instance.state = this._newState = newState; } diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js index eb8942a5209..b47495bca98 100644 --- a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js @@ -915,6 +915,33 @@ describe('ReactShallowRenderer', () => { expect(result.props.children).toEqual(3); }); + it('should not override state with stale values if prevState is spread within getDerivedStateFromProps', () => { + class SimpleComponent extends React.Component { + state = {value: 0}; + + static getDerivedStateFromProps(nextProps, prevState) { + return {...prevState}; + } + + updateState = () => { + this.setState(state => ({value: state.value + 1})); + }; + + render() { + return
{`value:${this.state.value}`}
; + } + } + + const shallowRenderer = createRenderer(); + let result = shallowRenderer.render(); + expect(result).toEqual(
value:0
); + + let instance = shallowRenderer.getMountedInstance(); + instance.updateState(); + result = shallowRenderer.getRenderOutput(); + expect(result).toEqual(
value:1
); + }); + it('can setState with an updater function', () => { let instance;