diff --git a/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js
new file mode 100644
index 0000000000000..d4413dd4e8752
--- /dev/null
+++ b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js
@@ -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(),
+ ).toWarnDev(
+ 'Warning: FunctionalComponent: Support for defaultProps ' +
+ 'will be removed from function components in a future major ' +
+ 'release. Use JavaScript default parameters instead.',
+ {withoutStack: true},
+ );
+ });
+});
diff --git a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
index f6359e20190b0..685a1cffb97e3 100644
--- a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
@@ -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
{props.test}
;
diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js
index f95a80b12a942..18c076bd39571 100644
--- a/packages/react-reconciler/src/ReactFiberBeginWork.js
+++ b/packages/react-reconciler/src/ReactFiberBeginWork.js
@@ -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';
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 259334080ccb0..ac92811f09541 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -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;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 8982c8f996d57..08baee4c30ca5 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -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() {
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 4183657076ea7..e1bb4ecae4bfd 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -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() {
diff --git a/packages/shared/forks/ReactFeatureFlags.persistent.js b/packages/shared/forks/ReactFeatureFlags.persistent.js
index 568626d09c4b1..c392336fc5188 100644
--- a/packages/shared/forks/ReactFeatureFlags.persistent.js
+++ b/packages/shared/forks/ReactFeatureFlags.persistent.js
@@ -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() {
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 80174516fcc83..a38d1f5ff8218 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -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() {
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 37a2a80402498..c8f1beb3e6288 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -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() {
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 6451c459028eb..284416c8255b2 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -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;