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.
This commit is contained in:
lunaruan
2019-07-25 15:44:03 -07:00
committed by GitHub
parent e0472709c8
commit 857deb2ed5
10 changed files with 81 additions and 0 deletions
@@ -0,0 +1,47 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
let React;
let ReactTestUtils;
let ReactFeatureFlags;
describe('ReactDeprecationWarnings', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactTestUtils = require('react-dom/test-utils');
ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = true;
});
afterEach(() => {
ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = false;
});
it('should warn when given defaultProps', () => {
function FunctionalComponent(props) {
return null;
}
FunctionalComponent.defaultProps = {
testProp: true,
};
expect(() =>
ReactTestUtils.renderIntoDocument(<FunctionalComponent />),
).toWarnDev(
'Warning: FunctionalComponent: Support for defaultProps ' +
'will be removed from function components in a future major ' +
'release. Use JavaScript default parameters instead.',
{withoutStack: true},
);
});
});
@@ -365,6 +365,8 @@ describe('ReactFunctionComponent', () => {
);
});
// TODO: change this test after we deprecate default props support
// for function components
it('should support default props and prop types', () => {
function Child(props) {
return <div>{props.test}</div>;
+20
View File
@@ -62,6 +62,7 @@ import {
enableSuspenseServerRenderer,
enableFlareAPI,
enableFundamentalAPI,
warnAboutDefaultPropsOnFunctionComponents,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import shallowEqual from 'shared/shallowEqual';
@@ -187,6 +188,7 @@ export let didWarnAboutReassigningProps;
let didWarnAboutMaxDuration;
let didWarnAboutRevealOrder;
let didWarnAboutTailOptions;
let didWarnAboutDefaultPropsOnFunctionComponent;
if (__DEV__) {
didWarnAboutBadClass = {};
@@ -198,6 +200,7 @@ if (__DEV__) {
didWarnAboutMaxDuration = false;
didWarnAboutRevealOrder = {};
didWarnAboutTailOptions = {};
didWarnAboutDefaultPropsOnFunctionComponent = {};
}
export function reconcileChildren(
@@ -1424,6 +1427,23 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) {
}
}
if (
warnAboutDefaultPropsOnFunctionComponents &&
Component.defaultProps !== undefined
) {
const componentName = getComponentName(Component) || 'Unknown';
if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
warningWithoutStack(
false,
'%s: Support for defaultProps will be removed from function components ' +
'in a future major release. Use JavaScript default parameters instead.',
componentName,
);
didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
}
}
if (typeof Component.getDerivedStateFromProps === 'function') {
const componentName = getComponentName(Component) || 'Unknown';
+5
View File
@@ -83,3 +83,8 @@ export const enableUserBlockingEvents = false;
// in the update queue. This allows reporting and tracing of what is causing
// the user to see a loading state.
export const enableSuspenseCallback = false;
// Part of the simplification of React.createElement so we can eventually move
// from React.createElement to React.jsx
// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
export const warnAboutDefaultPropsOnFunctionComponents = false;
@@ -38,6 +38,7 @@ export const warnAboutMissingMockScheduler = true;
export const revertPassiveEffectsChange = false;
export const enableUserBlockingEvents = false;
export const enableSuspenseCallback = false;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Only used in www builds.
export function addUserTimingListener() {
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = false;
export const revertPassiveEffectsChange = false;
export const enableUserBlockingEvents = false;
export const enableSuspenseCallback = false;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Only used in www builds.
export function addUserTimingListener() {
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = true;
export const revertPassiveEffectsChange = false;
export const enableUserBlockingEvents = false;
export const enableSuspenseCallback = false;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Only used in www builds.
export function addUserTimingListener() {
@@ -33,6 +33,7 @@ export const warnAboutMissingMockScheduler = false;
export const revertPassiveEffectsChange = false;
export const enableUserBlockingEvents = false;
export const enableSuspenseCallback = false;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Only used in www builds.
export function addUserTimingListener() {
@@ -33,6 +33,7 @@ export const enableJSXTransformAPI = true;
export const warnAboutMissingMockScheduler = true;
export const enableUserBlockingEvents = false;
export const enableSuspenseCallback = true;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Only used in www builds.
export function addUserTimingListener() {
@@ -78,6 +78,8 @@ export const warnAboutMissingMockScheduler = true;
export const enableSuspenseCallback = true;
export const warnAboutDefaultPropsOnFunctionComponents = false;
// Flow magic to verify the exports of this file match the original version.
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;