From cca307d33eaee6d09ef160b3026e6a2a064ca634 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 16 Nov 2022 18:32:13 -0500 Subject: [PATCH 1/5] Warn for defaultProps on memo components --- .../ReactDeprecationWarnings-test.internal.js | 21 +++++++++++++++++++ .../src/ReactFiberBeginWork.new.js | 14 +++++++++++++ .../src/ReactFiberBeginWork.old.js | 14 +++++++++++++ 3 files changed, 49 insertions(+) diff --git a/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js index a72c62cf7f442..45ce40283160b 100644 --- a/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js @@ -51,6 +51,27 @@ describe('ReactDeprecationWarnings', () => { ); }); + it('should warn when given defaultProps on a memoized function', () => { + const MemoComponent = React.memo(function FunctionalComponent(props) { + return null; + }); + + MemoComponent.defaultProps = { + testProp: true, + }; + + ReactNoop.render( +
+ +
, + ); + expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev( + 'Warning: FunctionalComponent: Support for defaultProps ' + + 'will be removed from memo components in a future major ' + + 'release. Use JavaScript default parameters instead.', + ); + }); + it('should warn when given string refs', () => { class RefComponent extends React.Component { render() { diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 27c086160ffe0..23991b9ea7b96 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -496,6 +496,20 @@ function updateMemoComponent( getComponentNameFromType(type), ); } + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + const componentName = getComponentNameFromType(type) || 'Unknown'; + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + console.error( + '%s: Support for defaultProps will be removed from memo components ' + + 'in a future major release. Use JavaScript default parameters instead.', + componentName, + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } } const child = createFiberFromTypeAndProps( Component.type, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index c3fed9d3c46a1..072850255f188 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -496,6 +496,20 @@ function updateMemoComponent( getComponentNameFromType(type), ); } + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + const componentName = getComponentNameFromType(type) || 'Unknown'; + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + console.error( + '%s: Support for defaultProps will be removed from memo components ' + + 'in a future major release. Use JavaScript default parameters instead.', + componentName, + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } } const child = createFiberFromTypeAndProps( Component.type, From a48bc3e53ecf6a94c9f5bddc6ba93366c2031116 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 16 Nov 2022 18:32:45 -0500 Subject: [PATCH 2/5] Enable warning for defaultProps on function components for everyone --- packages/shared/ReactFeatureFlags.js | 2 +- packages/shared/forks/ReactFeatureFlags.native-fb.js | 2 +- packages/shared/forks/ReactFeatureFlags.native-oss.js | 2 +- packages/shared/forks/ReactFeatureFlags.test-renderer.js | 2 +- packages/shared/forks/ReactFeatureFlags.test-renderer.native.js | 2 +- packages/shared/forks/ReactFeatureFlags.test-renderer.www.js | 2 +- packages/shared/forks/ReactFeatureFlags.testing.js | 2 +- packages/shared/forks/ReactFeatureFlags.testing.www.js | 2 +- packages/shared/forks/ReactFeatureFlags.www.js | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 3a52dfd100a5c..23e74d128cca8 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -213,7 +213,7 @@ export const disableTextareaChildren = 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; // deprecate later, not 18.0 +export const warnAboutDefaultPropsOnFunctionComponents = true; // deprecate later, not 18.0 // Enables a warning when trying to spread a 'key' to an element; // a deprecated pattern we want to get rid of in the future diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index f14d33de631d5..ac5f8de086201 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -41,7 +41,7 @@ export const warnAboutDeprecatedLifecycles = true; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 296d4012ab2f9..994fab5272e2c 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -31,7 +31,7 @@ export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 86f0d54eea169..2105a3e303ad2 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -31,7 +31,7 @@ export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index f734afa27227d..a9574a110aa24 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -31,7 +31,7 @@ export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 7ec00cbb2e9a9..3c0de034a7bf7 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -31,7 +31,7 @@ export const disableInputAttributeSyncing = false; export const enableScopeAPI = true; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = true; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index efe5ef51e26ab..3e7ec4d238c2e 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -31,7 +31,7 @@ export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = false; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index f9e6b26567c31..56fee4169077d 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -31,7 +31,7 @@ export const enableSchedulerDebugging = false; export const enableScopeAPI = true; export const enableCreateEventHandleAPI = true; export const enableSuspenseCallback = true; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const warnAboutStringRefs = true; export const disableLegacyContext = __EXPERIMENTAL__; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index b0516f7f498b7..513c7562c7f36 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -67,7 +67,7 @@ export const enableSchedulerDebugging = true; export const warnAboutDeprecatedLifecycles = true; export const disableLegacyContext = __EXPERIMENTAL__; export const warnAboutStringRefs = true; -export const warnAboutDefaultPropsOnFunctionComponents = false; +export const warnAboutDefaultPropsOnFunctionComponents = true; export const enableGetInspectorDataForInstanceInProduction = false; export const enableCache = true; From 2773ea8bc3de144e9a05b8d069e0877c8e1f1cfd Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 16 Nov 2022 19:12:53 -0500 Subject: [PATCH 3/5] Fix test --- .../src/__tests__/ReactLazy-test.internal.js | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index 682ceb87dfb94..8f196324d6e23 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -293,7 +293,12 @@ describe('ReactLazy', () => { await Promise.resolve(); - expect(Scheduler).toFlushAndYield(['Hi']); + expect(() => expect(Scheduler).toFlushAndYield(['Hi'])).toErrorDev( + 'Warning: T: Support for defaultProps ' + + 'will be removed from function components in a future major ' + + 'release. Use JavaScript default parameters instead.', + ); + expect(root).toMatchRenderedOutput('Hi'); T.defaultProps = {text: 'Hi again'}; @@ -343,7 +348,14 @@ describe('ReactLazy', () => { await Promise.resolve(); - expect(Scheduler).toFlushAndYield(['Lazy', 'Sibling', 'A']); + expect(() => + expect(Scheduler).toFlushAndYield(['Lazy', 'Sibling', 'A']), + ).toErrorDev( + 'Warning: LazyImpl: Support for defaultProps ' + + 'will be removed from function components in a future major ' + + 'release. Use JavaScript default parameters instead.', + ); + expect(root).toMatchRenderedOutput('SiblingA'); // Lazy should not re-render @@ -643,7 +655,12 @@ describe('ReactLazy', () => { expect(root).not.toMatchRenderedOutput('Hi Bye'); await Promise.resolve(); - expect(Scheduler).toFlushAndYield(['Hi Bye']); + expect(() => expect(Scheduler).toFlushAndYield(['Hi Bye'])).toErrorDev( + 'Warning: T: Support for defaultProps ' + + 'will be removed from function components in a future major ' + + 'release. Use JavaScript default parameters instead.', + ); + expect(root).toMatchRenderedOutput('Hi Bye'); root.update( @@ -732,7 +749,11 @@ describe('ReactLazy', () => { ); }); - async function verifyInnerPropTypesAreChecked(Add) { + async function verifyInnerPropTypesAreChecked( + Add, + shouldWarnAboutFunctionDefaultProps, + shouldWarnAboutMemoDefaultProps, + ) { const LazyAdd = lazy(() => fakeImport(Add)); expect(() => { LazyAdd.propTypes = {}; @@ -753,15 +774,28 @@ describe('ReactLazy', () => { ); expect(Scheduler).toFlushAndYield(['Loading...']); + expect(root).not.toMatchRenderedOutput('22'); // Mount await Promise.resolve(); expect(() => { Scheduler.unstable_flushAll(); - }).toErrorDev([ - 'Invalid prop `inner` of type `string` supplied to `Add`, expected `number`.', - ]); + }).toErrorDev( + shouldWarnAboutFunctionDefaultProps + ? [ + 'Add: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', + 'Invalid prop `inner` of type `string` supplied to `Add`, expected `number`.', + ] + : shouldWarnAboutMemoDefaultProps + ? [ + 'Add: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + 'Invalid prop `inner` of type `string` supplied to `Add`, expected `number`.', + ] + : [ + 'Invalid prop `inner` of type `string` supplied to `Add`, expected `number`.', + ], + ); expect(root).toMatchRenderedOutput('22'); // Update @@ -792,7 +826,7 @@ describe('ReactLazy', () => { Add.defaultProps = { innerWithDefault: 42, }; - await verifyInnerPropTypesAreChecked(Add); + await verifyInnerPropTypesAreChecked(Add, true); }); it('respects propTypes on function component without defaultProps', async () => { @@ -874,7 +908,7 @@ describe('ReactLazy', () => { Add.defaultProps = { innerWithDefault: 42, }; - await verifyInnerPropTypesAreChecked(Add); + await verifyInnerPropTypesAreChecked(Add, false, true); }); it('respects propTypes on outer memo component without defaultProps', async () => { @@ -901,7 +935,7 @@ describe('ReactLazy', () => { Add.defaultProps = { innerWithDefault: 42, }; - await verifyInnerPropTypesAreChecked(React.memo(Add)); + await verifyInnerPropTypesAreChecked(React.memo(Add), true); }); it('respects propTypes on inner memo component without defaultProps', async () => { @@ -944,9 +978,10 @@ describe('ReactLazy', () => { await Promise.resolve(); expect(() => { expect(Scheduler).toFlushAndYield(['Inner default text']); - }).toErrorDev( + }).toErrorDev([ + 'T: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', 'The prop `text` is marked as required in `T`, but its value is `undefined`', - ); + ]); expect(root).toMatchRenderedOutput('Inner default text'); // Update @@ -1058,7 +1093,11 @@ describe('ReactLazy', () => { // Mount await Promise.resolve(); - expect(Scheduler).toFlushWithoutYielding(); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev( + 'Unknown: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + ); expect(root).toMatchRenderedOutput('4'); // Update (shallowly equal) @@ -1142,7 +1181,12 @@ describe('ReactLazy', () => { // Mount await Promise.resolve(); - expect(Scheduler).toFlushWithoutYielding(); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev([ + 'Memo: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + 'Unknown: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + ]); expect(root).toMatchRenderedOutput('4'); // Update From 511f9d89fad817abc151186e8dbb218baf9ef5ce Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 16 Nov 2022 19:23:28 -0500 Subject: [PATCH 4/5] Upgrade deprecation warning tests These can be tested against the builds now. --- ...al.js => ReactDeprecationWarnings-test.js} | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) rename packages/react-dom/src/__tests__/{ReactDeprecationWarnings-test.internal.js => ReactDeprecationWarnings-test.js} (89%) diff --git a/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js similarity index 89% rename from packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js rename to packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js index 45ce40283160b..6b532c72b38bb 100644 --- a/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js @@ -10,7 +10,6 @@ 'use strict'; let React; -let ReactFeatureFlags; let ReactNoop; let Scheduler; let JSXDEVRuntime; @@ -19,19 +18,11 @@ describe('ReactDeprecationWarnings', () => { beforeEach(() => { jest.resetModules(); React = require('react'); - ReactFeatureFlags = require('shared/ReactFeatureFlags'); ReactNoop = require('react-noop-renderer'); Scheduler = require('scheduler'); if (__DEV__) { JSXDEVRuntime = require('react/jsx-dev-runtime'); } - ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = true; - ReactFeatureFlags.warnAboutStringRefs = true; - }); - - afterEach(() => { - ReactFeatureFlags.warnAboutDefaultPropsOnFunctionComponents = false; - ReactFeatureFlags.warnAboutStringRefs = false; }); it('should warn when given defaultProps', () => { @@ -95,9 +86,7 @@ describe('ReactDeprecationWarnings', () => { ); }); - it('should not warn when owner and self are the same for string refs', () => { - ReactFeatureFlags.warnAboutStringRefs = false; - + it('should warn when owner and self are the same for string refs', () => { class RefComponent extends React.Component { render() { return null; @@ -108,7 +97,11 @@ describe('ReactDeprecationWarnings', () => { return ; } } - ReactNoop.renderLegacySyncRoot(); + expect(() => { + ReactNoop.renderLegacySyncRoot(); + }).toErrorDev([ + 'Component "Component" contains the string ref "refComponent". Support for string refs will be removed in a future major release.', + ]); expect(Scheduler).toFlushWithoutYielding(); }); From eff7b63cdace8dee584d4e3d44aa3e242e9d9082 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 16 Nov 2022 19:41:41 -0500 Subject: [PATCH 5/5] Fix test --- .../ReactHooksInspectionIntegration-test.js | 6 +- .../src/__tests__/ReactDOMFizzServer-test.js | 106 +++++++++++------- .../__tests__/ReactFunctionComponent-test.js | 5 +- .../src/__tests__/ReactMemo-test.js | 13 ++- 4 files changed, 87 insertions(+), 43 deletions(-) diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index 2b9eea6d66f8a..af31e5e6fd600 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -898,7 +898,11 @@ describe('ReactHooksInspectionIntegration', () => { await LazyFoo; - Scheduler.unstable_flushAll(); + expect(() => { + Scheduler.unstable_flushAll(); + }).toErrorDev([ + 'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', + ]); const childFiber = renderer.root._currentFiber(); const tree = ReactDebugTools.inspectHooksOfFiber(childFiber); diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 7a4ca9d2464dd..030e5093e52fe 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -291,6 +291,18 @@ describe('ReactDOMFizzServer', () => { } it('should asynchronously load a lazy component', async () => { + const originalConsoleError = console.error; + const mockError = jest.fn(); + console.error = (...args) => { + if (args.length > 1) { + if (typeof args[1] === 'object') { + mockError(args[0].split('\n')[0]); + return; + } + } + mockError(...args.map(normalizeCodeLocInfo)); + }; + let resolveA; const LazyA = React.lazy(() => { return new Promise(r => { @@ -313,48 +325,66 @@ describe('ReactDOMFizzServer', () => { punctuation: '!', }; - await act(async () => { - const {pipe} = renderToPipeableStream( -
-
- }> - - -
+ try { + await act(async () => { + const {pipe} = renderToPipeableStream(
- }> - - -
+
+ }> + + +
+
+ }> + + +
+
, + ); + pipe(writable); + }); + + expect(getVisibleChildren(container)).toEqual( +
+
Loading...
+
Loading...
+
, + ); + await act(async () => { + resolveA({default: Text}); + }); + expect(getVisibleChildren(container)).toEqual( +
+
Hello
+
Loading...
+
, + ); + await act(async () => { + resolveB({default: TextWithPunctuation}); + }); + expect(getVisibleChildren(container)).toEqual( +
+
Hello
+
world!
, ); - pipe(writable); - }); - expect(getVisibleChildren(container)).toEqual( -
-
Loading...
-
Loading...
-
, - ); - await act(async () => { - resolveA({default: Text}); - }); - expect(getVisibleChildren(container)).toEqual( -
-
Hello
-
Loading...
-
, - ); - await act(async () => { - resolveB({default: TextWithPunctuation}); - }); - expect(getVisibleChildren(container)).toEqual( -
-
Hello
-
world!
-
, - ); + if (__DEV__) { + expect(mockError).toHaveBeenCalledWith( + 'Warning: %s: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.%s', + 'TextWithPunctuation', + '\n in TextWithPunctuation (at **)\n' + + ' in Lazy (at **)\n' + + ' in Suspense (at **)\n' + + ' in div (at **)\n' + + ' in div (at **)', + ); + } else { + expect(mockError).not.toHaveBeenCalled(); + } + } finally { + console.error = originalConsoleError; + } }); it('#23331: does not warn about hydration mismatches if something suspended in an earlier sibling', async () => { diff --git a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js index 9f51cb5fba4f1..10f53b6962ef3 100644 --- a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js @@ -367,11 +367,12 @@ describe('ReactFunctionComponent', () => { Child.defaultProps = {test: 2}; Child.propTypes = {test: PropTypes.string}; - expect(() => ReactTestUtils.renderIntoDocument()).toErrorDev( + expect(() => ReactTestUtils.renderIntoDocument()).toErrorDev([ + 'Warning: Child: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', 'Warning: Failed prop type: Invalid prop `test` of type `number` ' + 'supplied to `Child`, expected `string`.\n' + ' in Child (at **)', - ); + ]); }); it('should receive context', () => { diff --git a/packages/react-reconciler/src/__tests__/ReactMemo-test.js b/packages/react-reconciler/src/__tests__/ReactMemo-test.js index c58a11820cb28..cc6347bec9c02 100644 --- a/packages/react-reconciler/src/__tests__/ReactMemo-test.js +++ b/packages/react-reconciler/src/__tests__/ReactMemo-test.js @@ -75,6 +75,7 @@ describe('memo', () => { } ReactNoop.render(); expect(() => expect(Scheduler).toFlushWithoutYielding()).toErrorDev([ + 'App: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.', 'Warning: Function components cannot be given refs. Attempts to access ' + 'this ref will fail.', ]); @@ -441,7 +442,11 @@ describe('memo', () => { ); expect(Scheduler).toFlushAndYield(['Loading...']); await Promise.resolve(); - expect(Scheduler).toFlushAndYield([15]); + expect(() => { + expect(Scheduler).toFlushAndYield([15]); + }).toErrorDev([ + 'Counter: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + ]); expect(ReactNoop.getChildren()).toEqual([span(15)]); // Should bail out because props have not changed @@ -552,7 +557,11 @@ describe('memo', () => { , ); - expect(Scheduler).toFlushWithoutYielding(); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev([ + 'Inner: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.', + ]); // Mount expect(() => {