@samitouri / QOS-React-2 / commits / 86ee9e8488

NativeMethodsMixin DEV-only methods should not warn (#12212)

* Disable DEV-only warnings for RN NativeMethodsMixin/create-react-class * Tiny bit of cleanup * Make strict-mode suppression check a little more robust

Brian Vaughn committed Feb 11, 2018 at 16:29 UTC 86ee9e84880cab9f3804e7e59ec75bb75a4cf455
3 files changed +69 -10
packages/react-native-renderer/src/NativeMethodsMixin.js
+8
@@ -192,6 +192,8 @@ if (__DEV__) {
192 !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps,
193 'Do not override existing functions.',
194 );
195 + // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native,
196 + // Once these lifecycles have been remove from the reconciler.
197 NativeMethodsMixin_DEV.componentWillMount = function() {
198 throwOnStylesProp(this, this.props);
199 };
@@ -204,6 +206,12 @@ if (__DEV__) {
206 NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function(newProps) {
207 throwOnStylesProp(this, newProps);
208 };
209 +
210 + // React may warn about cWM/cWRP/cWU methods being deprecated.
211 + // Add a flag to suppress these warnings for this special case.
212 + // TODO (bvaughn) Remove this flag once the above methods have been removed.
213 + NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true;
214 + NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true;
215 }
216
217 export default NativeMethodsMixin;
packages/react-reconciler/src/ReactStrictModeWarnings.js
+5 -8
@@ -201,19 +201,16 @@ if (__DEV__) {
201 }
202
203 // Don't warn about react-lifecycles-compat polyfilled components.
204 - // Note that it is sufficient to check for the presence of a
205 - // single lifecycle, componentWillMount, with the polyfill flag.
204 if (
205 typeof instance.componentWillMount === 'function' &&
208 - instance.componentWillMount.__suppressDeprecationWarning === true
206 + instance.componentWillMount.__suppressDeprecationWarning !== true
207 ) {
210 - return;
211 - }
212 -
213 - if (typeof instance.componentWillMount === 'function') {
208 pendingComponentWillMountWarnings.push(fiber);
209 }
216 - if (typeof instance.componentWillReceiveProps === 'function') {
210 + if (
211 + typeof instance.componentWillReceiveProps === 'function' &&
212 + instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
213 + ) {
214 pendingComponentWillReceivePropsWarnings.push(fiber);
215 }
216 if (typeof instance.componentWillUpdate === 'function') {
packages/react/src/__tests__/createReactClassIntegration-test.internal.js
+56 -2
@@ -10,17 +10,17 @@
10 'use strict';
11
12 let React;
13 -let ReactDOM;
13 let ReactFeatureFlags;
14 let createReactClass;
15
16 describe('create-react-class-integration', () => {
17 beforeEach(() => {
18 + jest.resetModules();
19 +
20 ReactFeatureFlags = require('shared/ReactFeatureFlags');
21 ReactFeatureFlags.warnAboutDeprecatedLifecycles = true;
22
23 React = require('react');
23 - ReactDOM = require('react-dom');
24 createReactClass = require('create-react-class/factory')(
25 React.Component,
26 React.isValidElement,
@@ -31,6 +31,8 @@ describe('create-react-class-integration', () => {
31 // TODO (RFC #6) Merge this back into createReactClassIntegration-test once
32 // the 'warnAboutDeprecatedLifecycles' feature flag has been removed.
33 it('isMounted works', () => {
34 + const ReactDOM = require('react-dom');
35 +
36 const ops = [];
37 let instance;
38 const Component = createReactClass({
@@ -113,4 +115,56 @@ describe('create-react-class-integration', () => {
115 'after unmount: false',
116 ]);
117 });
118 +
119 + describe('ReactNative NativeMethodsMixin', () => {
120 + let ReactNative;
121 + let NativeMethodsMixin;
122 +
123 + beforeEach(() => {
124 + ReactNative = require('react-native-renderer');
125 + NativeMethodsMixin =
126 + ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
127 + .NativeMethodsMixin;
128 + });
129 +
130 + it('should not warn about default DEV-only legacy lifecycle methods', () => {
131 + const View = createReactClass({
132 + mixins: [NativeMethodsMixin],
133 + render: () => null,
134 + });
135 +
136 + ReactNative.render(<View />, 1);
137 + });
138 +
139 + it('should warn if users specify their own legacy componentWillMount', () => {
140 + const View = createReactClass({
141 + displayName: 'MyNativeComponent',
142 + mixins: [NativeMethodsMixin],
143 + componentWillMount: () => {},
144 + render: () => null,
145 + });
146 +
147 + expect(() => ReactNative.render(<View />, 1)).toLowPriorityWarnDev(
148 + 'componentWillMount is deprecated and will be removed in the next major version. ' +
149 + 'Use componentDidMount instead. As a temporary workaround, ' +
150 + 'you can rename to UNSAFE_componentWillMount.' +
151 + '\n\nPlease update the following components: MyNativeComponent',
152 + );
153 + });
154 +
155 + it('should warn if users specify their own legacy componentWillReceiveProps', () => {
156 + const View = createReactClass({
157 + displayName: 'MyNativeComponent',
158 + mixins: [NativeMethodsMixin],
159 + componentWillReceiveProps: () => {},
160 + render: () => null,
161 + });
162 +
163 + expect(() => ReactNative.render(<View />, 1)).toLowPriorityWarnDev(
164 + 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' +
165 + 'Use static getDerivedStateFromProps instead.' +
166 + '\n\nPlease update the following components: MyNativeComponent',
167 + );
168 + });
169 + });
170 });