Change:
<!-- Note: if the issue is about documentation or the website, please file it at: --Do you want to request a feature or report a bug? Bug What is the current behavior? In , the shallow renderer will set instance state in so the and will be the same in , which is different with the behavior of real rendering. If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle () or CodeSandbox () example below: given below class component: render with ReactDOM, the will return true since will be the old value : In shallow renderer, the behavior is different: What is the expected behavior? ShallowRenderer should not set the instance state in getDeriveStateFromProps, or in the we have no way to compare it. Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? I have tested this in master branch and 16.3, both not work. By the way this problem is related to airbnb/enzyme . If it's recoginzed as a bug I can provide a PR in next several days.

Discussion:
expect(log).toEqual([]); }); <ins> it('should pass previous state to shouldComponentUpdate even with getDerivedStateFromProps', () => { const divRef = React.createRef(); class SimpleComponent extends React.Component { constructor(props) { super(props); this.state = { value: props.value, }; } static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.value === prevState.value) { return null; } return {value: nextProps.value}; } shouldComponentUpdate(nextProps, nextState) { return nextState.value !== this.state.value; } render() { return <div ref={divRef}>value: {this.state.value}</div>; } } const div = document.createElement('div'); ReactDOM.render(<SimpleComponent value="initial" />, div); expect(divRef.current.textContent).toBe('value: initial'); ReactDOM.render(<SimpleComponent value="updated" />, div); expect(divRef.current.textContent).toBe('value: updated'); }); </ins> it('should call getSnapshotBeforeUpdate before mutations are committed', () => { const log = [];

this._updater, ); <del> this._updateStateFromStaticLifecycle(element.props); </del> <ins> if (typeof element.type.getDerivedStateFromProps === 'function') { const partialState = element.type.getDerivedStateFromProps.call( null, element.props, this._instance.state, ); if (partialState != null) { this._instance.state = Object.assign( {}, this._instance.state, partialState, ); } } </ins> if (element.type.hasOwnProperty('contextTypes')) { currentlyValidatingElement = element;

} } } <del> this._updateStateFromStaticLifecycle(props); </del> // Read state after cWRP in case it calls setState <del> const state = this._newState || oldState; </del> <ins> let state = this._newState || oldState; if (typeof type.getDerivedStateFromProps === 'function') { const partialState = type.getDerivedStateFromProps.call( null, props, state, ); if (partialState != null) { state = Object.assign({}, state, partialState); } } </ins> let shouldUpdate = true; if (this._forcedUpdate) {

this._instance.context = context; this._instance.props = props; this._instance.state = state; <ins> this._newState = null; </ins> if (shouldUpdate) { this._rendered = this._instance.render();

// Intentionally do not call componentDidUpdate() // because DOM refs are not available. } <del> _updateStateFromStaticLifecycle(props: Object) { if (this._element === null) { return; } const {type} = this._element; if (typeof type.getDerivedStateFromProps === 'function') { const oldState = this._newState || this._instance.state; const partialState = type.getDerivedStateFromProps.call( null, props, oldState, ); if (partialState != null) { const newState = Object.assign({}, oldState, partialState); this._instance.state = this._newState = newState; } } } </del> } let currentlyValidatingElement = null;

expect(result).toEqual(<div>value:1</div>); }); <ins> it('should pass previous state to shouldComponentUpdate even with getDerivedStateFromProps', () => { class SimpleComponent extends React.Component { constructor(props) { super(props); this.state = { value: props.value, }; } static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.value === prevState.value) { return null; } return {value: nextProps.value}; } shouldComponentUpdate(nextProps, nextState) { return nextState.value !== this.state.value; } render() { return <div>{`value:${this.state.value}`}</div>; } } const shallowRenderer = createRenderer(); const initialResult = shallowRenderer.render( <SimpleComponent value="initial" />, ); expect(initialResult).toEqual(<div>value:initial</div>); const updatedResult = shallowRenderer.render( <SimpleComponent value="updated" />, ); expect(updatedResult).toEqual(<div>value:updated</div>); }); </ins> it('can setState with an updater function', () => { let instance;