diff --git a/src/ReactShallowRenderer.js b/src/ReactShallowRenderer.js
index 8d80221..131db2d 100644
--- a/src/ReactShallowRenderer.js
+++ b/src/ReactShallowRenderer.js
@@ -139,20 +139,18 @@ class ReactShallowRenderer {
) {
const beforeState = this._newState;
- if (typeof this._instance.componentWillMount === 'function') {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- if (typeof element.type.getDerivedStateFromProps !== 'function') {
- this._instance.componentWillMount();
- }
- }
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
if (
- typeof this._instance.UNSAFE_componentWillMount === 'function' &&
- typeof element.type.getDerivedStateFromProps !== 'function'
+ typeof element.type.getDerivedStateFromProps !== 'function' &&
+ typeof this._instance.getSnapshotBeforeUpdate !== 'function'
) {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- this._instance.UNSAFE_componentWillMount();
+ if (typeof this._instance.componentWillMount === 'function') {
+ this._instance.componentWillMount();
+ }
+ if (typeof this._instance.UNSAFE_componentWillMount === 'function') {
+ this._instance.UNSAFE_componentWillMount();
+ }
}
// setState may have been called during cWM
@@ -173,20 +171,20 @@ class ReactShallowRenderer {
const oldProps = this._instance.props;
if (oldProps !== props) {
- if (typeof this._instance.componentWillReceiveProps === 'function') {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- if (typeof element.type.getDerivedStateFromProps !== 'function') {
- this._instance.componentWillReceiveProps(props, context);
- }
- }
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
if (
- typeof this._instance.UNSAFE_componentWillReceiveProps === 'function' &&
- typeof element.type.getDerivedStateFromProps !== 'function'
+ typeof element.type.getDerivedStateFromProps !== 'function' &&
+ typeof this._instance.getSnapshotBeforeUpdate !== 'function'
) {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- this._instance.UNSAFE_componentWillReceiveProps(props, context);
+ if (typeof this._instance.componentWillReceiveProps === 'function') {
+ this._instance.componentWillReceiveProps(props, context);
+ }
+ if (
+ typeof this._instance.UNSAFE_componentWillReceiveProps === 'function'
+ ) {
+ this._instance.UNSAFE_componentWillReceiveProps(props, context);
+ }
}
this._updateStateFromStaticLifecycle(props);
@@ -211,20 +209,18 @@ class ReactShallowRenderer {
}
if (shouldUpdate) {
- if (typeof this._instance.componentWillUpdate === 'function') {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- if (typeof type.getDerivedStateFromProps !== 'function') {
- this._instance.componentWillUpdate(props, state, context);
- }
- }
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
if (
- typeof this._instance.UNSAFE_componentWillUpdate === 'function' &&
- typeof type.getDerivedStateFromProps !== 'function'
+ typeof element.type.getDerivedStateFromProps !== 'function' &&
+ typeof this._instance.getSnapshotBeforeUpdate !== 'function'
) {
- // In order to support react-lifecycles-compat polyfilled components,
- // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
- this._instance.UNSAFE_componentWillUpdate(props, state, context);
+ if (typeof this._instance.componentWillUpdate === 'function') {
+ this._instance.componentWillUpdate(props, state, context);
+ }
+ if (typeof this._instance.UNSAFE_componentWillUpdate === 'function') {
+ this._instance.UNSAFE_componentWillUpdate(props, state, context);
+ }
}
}
diff --git a/src/__tests__/ReactShallowRenderer-test.js b/src/__tests__/ReactShallowRenderer-test.js
index 2c6618d..7e60bde 100644
--- a/src/__tests__/ReactShallowRenderer-test.js
+++ b/src/__tests__/ReactShallowRenderer-test.js
@@ -128,6 +128,48 @@ describe('ReactShallowRenderer', () => {
shallowRenderer.render();
});
+ it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', () => {
+ class Component extends React.Component {
+ getSnapshotBeforeUpdate() {
+ return null;
+ }
+ componentWillMount() {
+ throw Error('unexpected');
+ }
+ componentWillReceiveProps() {
+ throw Error('unexpected');
+ }
+ componentWillUpdate() {
+ throw Error('unexpected');
+ }
+ render() {
+ return null;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render();
+ shallowRenderer.render();
+ });
+
+ it('should not call getSnapshotBeforeUpdate or componentDidUpdate when updating since refs wont exist', () => {
+ class Component extends React.Component {
+ getSnapshotBeforeUpdate() {
+ throw Error('unexpected');
+ }
+ componentDidUpdate() {
+ throw Error('unexpected');
+ }
+ render() {
+ return null;
+ }
+ }
+
+ const shallowRenderer = createRenderer();
+ shallowRenderer.render();
+ shallowRenderer.render();
+ });
+
it('should only render 1 level deep', () => {
function Parent() {
return (