Warn when Using DefaultProps on Function Components (#16210)
As part of the process to deprecate defaultProps on function components (as per a larger proposal outlined in (https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md)), add a warning whenever someone does this.
lunaruan committed
Jul 25, 2019 at 15:44 UTC
857deb2ed59f58a1bd3887f2ab62ff1df809acba
10 files changed
+81
packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js
new
+47
@@ -0,0 +1,47 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails react-core
8
+ */
9
+
10
+'use strict';
11
+
12
+let React;
13
+let ReactTestUtils;
14
+let ReactFeatureFlags;
15
+
16
+describe('ReactDeprecationWarnings', () => {
17
+ beforeEach(() => {
18
+ jest.resetModules();
19
+ React = require('react');
20
+ ReactFeatureFlags = require('shared/ReactFeatureFlags');
21
+ ReactTestUtils = require('react-dom/test-utils');
22
+ ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = true;
23
+ });
24
+
25
+ afterEach(() => {
26
+ ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = false;
27
+ });
28
+
29
+ it('should warn when given defaultProps', () => {
30
+ function FunctionalComponent(props) {
31
+ return null;
32
+ }
33
+
34
+ FunctionalComponent.defaultProps = {
35
+ testProp: true,
36
+ };
37
+
38
+ expect(() =>
39
+ ReactTestUtils.renderIntoDocument(<FunctionalComponent />),
40
+ ).toWarnDev(
41
+ 'Warning: FunctionalComponent: Support for defaultProps ' +
42
+ 'will be removed from function components in a future major ' +
43
+ 'release. Use JavaScript default parameters instead.',
44
+ {withoutStack: true},
45
+ );
46
+ });
47
+});
packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
+2
@@ -365,6 +365,8 @@ describe('ReactFunctionComponent', () => {
365
);
366
});
367
368
+ // TODO: change this test after we deprecate default props support
369
+ // for function components
370
it('should support default props and prop types', () => {
371
function Child(props) {
372
return <div>{props.test}</div>;
packages/react-reconciler/src/ReactFiberBeginWork.js
+20
@@ -62,6 +62,7 @@ import {
62
enableSuspenseServerRenderer,
63
enableFlareAPI,
64
enableFundamentalAPI,
65
+ warnAboutDefaultPropsOnFunctionComponents,
66
} from 'shared/ReactFeatureFlags';
67
import invariant from 'shared/invariant';
68
import shallowEqual from 'shared/shallowEqual';
@@ -187,6 +188,7 @@ export let didWarnAboutReassigningProps;
188
let didWarnAboutMaxDuration;
189
let didWarnAboutRevealOrder;
190
let didWarnAboutTailOptions;
191
+let didWarnAboutDefaultPropsOnFunctionComponent;
192
193
if (__DEV__) {
194
didWarnAboutBadClass = {};
@@ -198,6 +200,7 @@ if (__DEV__) {
200
didWarnAboutMaxDuration = false;
201
didWarnAboutRevealOrder = {};
202
didWarnAboutTailOptions = {};
203
+ didWarnAboutDefaultPropsOnFunctionComponent = {};
204
}
205
206
export function reconcileChildren(
@@ -1424,6 +1427,23 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) {
1427
}
1428
}
1429
1430
+ if (
1431
+ warnAboutDefaultPropsOnFunctionComponents &&
1432
+ Component.defaultProps !== undefined
1433
+ ) {
1434
+ const componentName = getComponentName(Component) || 'Unknown';
1435
+
1436
+ if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
1437
+ warningWithoutStack(
1438
+ false,
1439
+ '%s: Support for defaultProps will be removed from function components ' +
1440
+ 'in a future major release. Use JavaScript default parameters instead.',
1441
+ componentName,
1442
+ );
1443
+ didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
1444
+ }
1445
+ }
1446
+
1447
if (typeof Component.getDerivedStateFromProps === 'function') {
1448
const componentName = getComponentName(Component) || 'Unknown';
1449
packages/shared/ReactFeatureFlags.js
+5
@@ -83,3 +83,8 @@ export const enableUserBlockingEvents = false;
83
// in the update queue. This allows reporting and tracing of what is causing
84
// the user to see a loading state.
85
export const enableSuspenseCallback = false;
86
+
87
+// Part of the simplification of React.createElement so we can eventually move
88
+// from React.createElement to React.jsx
89
+// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
90
+export const warnAboutDefaultPropsOnFunctionComponents = false;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -38,6 +38,7 @@ export const warnAboutMissingMockScheduler = true;
38
export const revertPassiveEffectsChange = false;
39
export const enableUserBlockingEvents = false;
40
export const enableSuspenseCallback = false;
41
+export const warnAboutDefaultPropsOnFunctionComponents = false;
42
43
// Only used in www builds.
44
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = false;
33
export const revertPassiveEffectsChange = false;
34
export const enableUserBlockingEvents = false;
35
export const enableSuspenseCallback = false;
36
+export const warnAboutDefaultPropsOnFunctionComponents = false;
37
38
// Only used in www builds.
39
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.persistent.js
+1
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = true;
33
export const revertPassiveEffectsChange = false;
34
export const enableUserBlockingEvents = false;
35
export const enableSuspenseCallback = false;
36
+export const warnAboutDefaultPropsOnFunctionComponents = false;
37
38
// Only used in www builds.
39
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = false;
33
export const revertPassiveEffectsChange = false;
34
export const enableUserBlockingEvents = false;
35
export const enableSuspenseCallback = false;
36
+export const warnAboutDefaultPropsOnFunctionComponents = false;
37
38
// Only used in www builds.
39
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -33,6 +33,7 @@ export const enableJSXTransformAPI = true;
33
export const warnAboutMissingMockScheduler = true;
34
export const enableUserBlockingEvents = false;
35
export const enableSuspenseCallback = true;
36
+export const warnAboutDefaultPropsOnFunctionComponents = false;
37
38
// Only used in www builds.
39
export function addUserTimingListener() {
packages/shared/forks/ReactFeatureFlags.www.js
+2
@@ -78,6 +78,8 @@ export const warnAboutMissingMockScheduler = true;
78
79
export const enableSuspenseCallback = true;
80
81
+export const warnAboutDefaultPropsOnFunctionComponents = false;
82
+
83
// Flow magic to verify the exports of this file match the original version.
84
// eslint-disable-next-line no-unused-vars
85
type Check<_X, Y: _X, X: Y = _X> = null;