diff --git a/packages/react-native-renderer/src/NativeMethodsMixin.js b/packages/react-native-renderer/src/NativeMethodsMixin.js
index e2cad55458..aec0442934 100644
--- a/packages/react-native-renderer/src/NativeMethodsMixin.js
+++ b/packages/react-native-renderer/src/NativeMethodsMixin.js
@@ -192,6 +192,8 @@ if (__DEV__) {
!NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps,
'Do not override existing functions.',
);
+ // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native,
+ // Once these lifecycles have been remove from the reconciler.
NativeMethodsMixin_DEV.componentWillMount = function() {
throwOnStylesProp(this, this.props);
};
@@ -204,6 +206,12 @@ if (__DEV__) {
NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function(newProps) {
throwOnStylesProp(this, newProps);
};
+
+ // React may warn about cWM/cWRP/cWU methods being deprecated.
+ // Add a flag to suppress these warnings for this special case.
+ // TODO (bvaughn) Remove this flag once the above methods have been removed.
+ NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true;
+ NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true;
}
export default NativeMethodsMixin;
diff --git a/packages/react-reconciler/src/ReactStrictModeWarnings.js b/packages/react-reconciler/src/ReactStrictModeWarnings.js
index 8604526ad7..0afaa74d52 100644
--- a/packages/react-reconciler/src/ReactStrictModeWarnings.js
+++ b/packages/react-reconciler/src/ReactStrictModeWarnings.js
@@ -201,19 +201,16 @@ if (__DEV__) {
}
// Don't warn about react-lifecycles-compat polyfilled components.
- // Note that it is sufficient to check for the presence of a
- // single lifecycle, componentWillMount, with the polyfill flag.
if (
typeof instance.componentWillMount === 'function' &&
- instance.componentWillMount.__suppressDeprecationWarning === true
+ instance.componentWillMount.__suppressDeprecationWarning !== true
) {
- return;
- }
-
- if (typeof instance.componentWillMount === 'function') {
pendingComponentWillMountWarnings.push(fiber);
}
- if (typeof instance.componentWillReceiveProps === 'function') {
+ if (
+ typeof instance.componentWillReceiveProps === 'function' &&
+ instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
+ ) {
pendingComponentWillReceivePropsWarnings.push(fiber);
}
if (typeof instance.componentWillUpdate === 'function') {
diff --git a/packages/react/src/__tests__/createReactClassIntegration-test.internal.js b/packages/react/src/__tests__/createReactClassIntegration-test.internal.js
index 2fcd864dde..d79a194996 100644
--- a/packages/react/src/__tests__/createReactClassIntegration-test.internal.js
+++ b/packages/react/src/__tests__/createReactClassIntegration-test.internal.js
@@ -10,17 +10,17 @@
'use strict';
let React;
-let ReactDOM;
let ReactFeatureFlags;
let createReactClass;
describe('create-react-class-integration', () => {
beforeEach(() => {
+ jest.resetModules();
+
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.warnAboutDeprecatedLifecycles = true;
React = require('react');
- ReactDOM = require('react-dom');
createReactClass = require('create-react-class/factory')(
React.Component,
React.isValidElement,
@@ -31,6 +31,8 @@ describe('create-react-class-integration', () => {
// TODO (RFC #6) Merge this back into createReactClassIntegration-test once
// the 'warnAboutDeprecatedLifecycles' feature flag has been removed.
it('isMounted works', () => {
+ const ReactDOM = require('react-dom');
+
const ops = [];
let instance;
const Component = createReactClass({
@@ -113,4 +115,56 @@ describe('create-react-class-integration', () => {
'after unmount: false',
]);
});
+
+ describe('ReactNative NativeMethodsMixin', () => {
+ let ReactNative;
+ let NativeMethodsMixin;
+
+ beforeEach(() => {
+ ReactNative = require('react-native-renderer');
+ NativeMethodsMixin =
+ ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
+ .NativeMethodsMixin;
+ });
+
+ it('should not warn about default DEV-only legacy lifecycle methods', () => {
+ const View = createReactClass({
+ mixins: [NativeMethodsMixin],
+ render: () => null,
+ });
+
+ ReactNative.render(, 1);
+ });
+
+ it('should warn if users specify their own legacy componentWillMount', () => {
+ const View = createReactClass({
+ displayName: 'MyNativeComponent',
+ mixins: [NativeMethodsMixin],
+ componentWillMount: () => {},
+ render: () => null,
+ });
+
+ expect(() => ReactNative.render(, 1)).toLowPriorityWarnDev(
+ 'componentWillMount is deprecated and will be removed in the next major version. ' +
+ 'Use componentDidMount instead. As a temporary workaround, ' +
+ 'you can rename to UNSAFE_componentWillMount.' +
+ '\n\nPlease update the following components: MyNativeComponent',
+ );
+ });
+
+ it('should warn if users specify their own legacy componentWillReceiveProps', () => {
+ const View = createReactClass({
+ displayName: 'MyNativeComponent',
+ mixins: [NativeMethodsMixin],
+ componentWillReceiveProps: () => {},
+ render: () => null,
+ });
+
+ expect(() => ReactNative.render(, 1)).toLowPriorityWarnDev(
+ 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' +
+ 'Use static getDerivedStateFromProps instead.' +
+ '\n\nPlease update the following components: MyNativeComponent',
+ );
+ });
+ });
});