From a2dc4efed28b6ba04b9ea45009c6f3735ede2e18 Mon Sep 17 00:00:00 2001 From: Liam O'Boyle Date: Thu, 22 Aug 2019 08:22:14 +1000 Subject: [PATCH] Use UNSAFE_ lifecycle event names where supported. This provides forward compatibility with React 17.x for those still using the react-redux 5.x series by detecting support for the UNSAFE_ prefixed lifecycle event names (using `React.createContext` as a feature check as it avoids semver checking but was introduced in React 16.3 at the same time as the UNSAFE_ prefixes). --- src/components/Provider.js | 10 ++++++++-- src/components/connectAdvanced.js | 11 ++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/components/Provider.js b/src/components/Provider.js index f78e25e65..38d70879f 100644 --- a/src/components/Provider.js +++ b/src/components/Provider.js @@ -1,8 +1,10 @@ -import { Component, Children } from 'react' +import React, { Component, Children } from 'react' import PropTypes from 'prop-types' import { storeShape, subscriptionShape } from '../utils/PropTypes' import warning from '../utils/warning' +const prefixUnsafeLifecycleMethods = parseFloat(React.version) >= 16.3 + let didWarnAboutReceivingStore = false function warnAboutReceivingStore() { if (didWarnAboutReceivingStore) { @@ -38,7 +40,11 @@ export function createProvider(storeKey = 'store') { } if (process.env.NODE_ENV !== 'production') { - Provider.prototype.componentWillReceiveProps = function (nextProps) { + // Use UNSAFE_ event name where supported + const eventName = prefixUnsafeLifecycleMethods + ? 'UNSAFE_componentWillReceiveProps' + : 'componentWillReceiveProps' + Provider.prototype[eventName] = function (nextProps) { if (this[storeKey] !== nextProps.store) { warnAboutReceivingStore() } diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 00ab7683c..9222f1645 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -1,11 +1,13 @@ import hoistStatics from 'hoist-non-react-statics' import invariant from 'invariant' -import { Component, createElement } from 'react' +import React, { Component, createElement } from 'react' import { isValidElementType } from 'react-is' import Subscription from '../utils/Subscription' import { storeShape, subscriptionShape } from '../utils/PropTypes' +const prefixUnsafeLifecycleMethods = parseFloat(React.version) >= 16.3 + let hotReloadingVersion = 0 const dummyState = {} function noop() {} @@ -160,6 +162,7 @@ export default function connectAdvanced( if (this.selector.shouldComponentUpdate) this.forceUpdate() } + // Note: this is renamed below to the UNSAFE_ version in React >=16.3.0 componentWillReceiveProps(nextProps) { this.selector.run(nextProps) } @@ -262,6 +265,12 @@ export default function connectAdvanced( } } + if (prefixUnsafeLifecycleMethods) { + // Use UNSAFE_ event name where supported + Connect.UNSAFE_componentWillReceiveProps = Connect.componentWillReceiveProps + delete Connect.componentWillReceiveProps + } + /* eslint-enable react/no-deprecated */ Connect.WrappedComponent = WrappedComponent