diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js index 49be844e8be8e..9cafeeb2f15e2 100644 --- a/packages/react-test-renderer/src/ReactShallowRenderer.js +++ b/packages/react-test-renderer/src/ReactShallowRenderer.js @@ -301,6 +301,11 @@ class Updater { partialState = partialState(currentState, publicInstance.props); } + // Null and undefined are treated as no-ops. + if (partialState === null || partialState === undefined) { + return; + } + this._renderer._newState = { ...currentState, ...partialState, diff --git a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js index 59ea0d9c690b1..b20f316d9ed68 100644 --- a/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js @@ -1305,4 +1305,32 @@ describe('ReactShallowRenderer', () => { 'UNSAFE_componentWillUpdate', ]); }); + + it('should stop the upade when setState returns null or undefined', () => { + const log = []; + let instance; + class Component extends React.Component { + constructor(props) { + super(props); + this.state = { + count: 0, + }; + } + render() { + log.push('render'); + instance = this; + return null; + } + } + const shallowRenderer = createRenderer(); + shallowRenderer.render(); + log.length = 0; + instance.setState(() => null); + instance.setState(() => undefined); + instance.setState(null); + instance.setState(undefined); + expect(log).toEqual([]); + instance.setState(state => ({count: state.count + 1})); + expect(log).toEqual(['render']); + }); });