@samitouri / QOS-React-1 / commits / 602917c8cb

Cleanup disableDefaultPropsExceptForClasses flag (#33648)

Jan Kassens committed Jul 1, 2025 at 15:52 UTC 602917c8cb521e6f9b8eae7070985e2a698fc0d0
21 files changed +18 -1023
packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
+1 -53
@@ -14,7 +14,6 @@ let React;
14 let ReactTestRenderer;
15 let ReactDebugTools;
16 let act;
17 -let assertConsoleErrorDev;
17 let useMemoCache;
18
19 function normalizeSourceLoc(tree) {
@@ -34,7 +33,7 @@ describe('ReactHooksInspectionIntegration', () => {
33 jest.resetModules();
34 React = require('react');
35 ReactTestRenderer = require('react-test-renderer');
37 - ({act, assertConsoleErrorDev} = require('internal-test-utils'));
36 + ({act} = require('internal-test-utils'));
37 ReactDebugTools = require('react-debug-tools');
38 useMemoCache = require('react/compiler-runtime').c;
39 });
@@ -2321,57 +2320,6 @@ describe('ReactHooksInspectionIntegration', () => {
2320 });
2321 });
2322
2324 - // @gate !disableDefaultPropsExceptForClasses
2325 - it('should support defaultProps and lazy', async () => {
2326 - const Suspense = React.Suspense;
2327 -
2328 - function Foo(props) {
2329 - const [value] = React.useState(props.defaultValue.slice(0, 3));
2330 - return <div>{value}</div>;
2331 - }
2332 - Foo.defaultProps = {
2333 - defaultValue: 'default',
2334 - };
2335 -
2336 - async function fakeImport(result) {
2337 - return {default: result};
2338 - }
2339 -
2340 - const LazyFoo = React.lazy(() => fakeImport(Foo));
2341 -
2342 - const renderer = ReactTestRenderer.create(
2343 - <Suspense fallback="Loading...">
2344 - <LazyFoo />
2345 - </Suspense>,
2346 - );
2347 -
2348 - await act(async () => await LazyFoo);
2349 - assertConsoleErrorDev([
2350 - 'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
2351 - ]);
2352 -
2353 - const childFiber = renderer.root._currentFiber();
2354 - const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
2355 - expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
2356 - [
2357 - {
2358 - "debugInfo": null,
2359 - "hookSource": {
2360 - "columnNumber": 0,
2361 - "fileName": "**",
2362 - "functionName": "Foo",
2363 - "lineNumber": 0,
2364 - },
2365 - "id": 0,
2366 - "isStateEditable": true,
2367 - "name": "State",
2368 - "subHooks": [],
2369 - "value": "def",
2370 - },
2371 - ]
2372 - `);
2373 - });
2374 -
2323 // This test case is based on an open source bug report:
2324 // https://github.com/facebookincubator/redux-react-hook/issues/34#issuecomment-466693787
2325 it('should properly advance the current hook for useContext', async () => {
packages/react-dom/src/__tests__/ReactDeprecationWarnings-test.js deleted
-72
@@ -1,72 +0,0 @@
1 -/**
2 - * Copyright (c) Meta Platforms, Inc. and 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 ReactNoop;
14 -let waitForAll;
15 -let assertConsoleErrorDev;
16 -
17 -describe('ReactDeprecationWarnings', () => {
18 - beforeEach(() => {
19 - jest.resetModules();
20 - React = require('react');
21 - ReactNoop = require('react-noop-renderer');
22 - const InternalTestUtils = require('internal-test-utils');
23 - waitForAll = InternalTestUtils.waitForAll;
24 - assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
25 - });
26 -
27 - // @gate !disableDefaultPropsExceptForClasses || !__DEV__
28 - it('should warn when given defaultProps', async () => {
29 - function FunctionalComponent(props) {
30 - return null;
31 - }
32 -
33 - FunctionalComponent.defaultProps = {
34 - testProp: true,
35 - };
36 -
37 - ReactNoop.render(<FunctionalComponent />);
38 - await waitForAll([]);
39 - assertConsoleErrorDev([
40 - 'FunctionalComponent: Support for defaultProps ' +
41 - 'will be removed from function components in a future major ' +
42 - 'release. Use JavaScript default parameters instead.\n' +
43 - ' in FunctionalComponent (at **)',
44 - ]);
45 - });
46 -
47 - // @gate !disableDefaultPropsExceptForClasses || !__DEV__
48 - it('should warn when given defaultProps on a memoized function', async () => {
49 - const MemoComponent = React.memo(function FunctionalComponent(props) {
50 - return null;
51 - });
52 -
53 - MemoComponent.defaultProps = {
54 - testProp: true,
55 - };
56 -
57 - ReactNoop.render(
58 - <div>
59 - <MemoComponent />
60 - </div>,
61 - );
62 - await waitForAll([]);
63 - assertConsoleErrorDev(
64 - [
65 - 'FunctionalComponent: Support for defaultProps ' +
66 - 'will be removed from memo components in a future major ' +
67 - 'release. Use JavaScript default parameters instead.',
68 - ],
69 - {withoutStack: true},
70 - );
71 - });
72 -});
packages/react-dom/src/__tests__/ReactFunctionComponent-test.js
-21
@@ -205,27 +205,6 @@ describe('ReactFunctionComponent', () => {
205 ]);
206 });
207
208 - // @gate !disableDefaultPropsExceptForClasses
209 - it('should support default props', async () => {
210 - function Child(props) {
211 - return <div>{props.test}</div>;
212 - }
213 - Child.defaultProps = {test: 2};
214 -
215 - const container = document.createElement('div');
216 - const root = ReactDOMClient.createRoot(container);
217 -
218 - await act(() => {
219 - root.render(<Child />);
220 - });
221 - expect(container.textContent).toBe('2');
222 - assertConsoleErrorDev([
223 - 'Child: Support for defaultProps will be removed from function components in a future major release. ' +
224 - 'Use JavaScript default parameters instead.\n' +
225 - ' in Child (at **)',
226 - ]);
227 - });
228 -
208 // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents
209 it('should receive context', async () => {
210 class Parent extends React.Component {
packages/react-reconciler/src/ReactFiberBeginWork.js
+9 -86
@@ -117,7 +117,6 @@ import {
117 enableCPUSuspense,
118 enablePostpone,
119 disableLegacyMode,
120 - disableDefaultPropsExceptForClasses,
120 enableHydrationLaneScheduling,
121 enableViewTransition,
122 enableFragmentRefs,
@@ -258,7 +257,6 @@ import {
257 updateClassInstance,
258 resolveClassComponentProps,
259 } from './ReactFiberClassComponent';
261 -import {resolveDefaultPropsOnNonClassComponent} from './ReactFiberLazyComponent';
260 import {
261 createFiberFromTypeAndProps,
262 createFiberFromFragment,
@@ -327,7 +325,6 @@ let didWarnAboutGetDerivedStateOnFunctionComponent;
325 export let didWarnAboutReassigningProps: boolean;
326 let didWarnAboutRevealOrder;
327 let didWarnAboutTailOptions;
330 -let didWarnAboutDefaultPropsOnFunctionComponent;
328 let didWarnAboutClassNameOnViewTransition;
329
330 if (__DEV__) {
@@ -338,7 +335,6 @@ if (__DEV__) {
335 didWarnAboutReassigningProps = false;
336 didWarnAboutRevealOrder = ({}: {[string]: boolean});
337 didWarnAboutTailOptions = ({}: {[string]: boolean});
341 - didWarnAboutDefaultPropsOnFunctionComponent = ({}: {[string]: boolean});
338 didWarnAboutClassNameOnViewTransition = ({}: {[string]: boolean});
339 }
340
@@ -482,13 +478,7 @@ function updateMemoComponent(
478 ): null | Fiber {
479 if (current === null) {
480 const type = Component.type;
485 - if (
486 - isSimpleFunctionComponent(type) &&
487 - Component.compare === null &&
488 - // SimpleMemoComponent codepath doesn't resolve outer props either.
489 - (disableDefaultPropsExceptForClasses ||
490 - Component.defaultProps === undefined)
491 - ) {
481 + if (isSimpleFunctionComponent(type) && Component.compare === null) {
482 let resolvedType = type;
483 if (__DEV__) {
484 resolvedType = resolveFunctionForHotReloading(type);
@@ -509,21 +499,6 @@ function updateMemoComponent(
499 renderLanes,
500 );
501 }
512 - if (!disableDefaultPropsExceptForClasses) {
513 - if (__DEV__) {
514 - if (Component.defaultProps !== undefined) {
515 - const componentName = getComponentNameFromType(type) || 'Unknown';
516 - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
517 - console.error(
518 - '%s: Support for defaultProps will be removed from memo components ' +
519 - 'in a future major release. Use JavaScript default parameters instead.',
520 - componentName,
521 - );
522 - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
523 - }
524 - }
525 - }
526 - }
502 const child = createFiberFromTypeAndProps(
503 Component.type,
504 null,
@@ -2072,9 +2047,6 @@ function mountLazyComponent(
2047 renderLanes,
2048 );
2049 } else {
2075 - const resolvedProps = disableDefaultPropsExceptForClasses
2076 - ? props
2077 - : resolveDefaultPropsOnNonClassComponent(Component, props);
2050 workInProgress.tag = FunctionComponent;
2051 if (__DEV__) {
2052 validateFunctionComponentInDev(workInProgress, Component);
@@ -2085,16 +2057,13 @@ function mountLazyComponent(
2057 null,
2058 workInProgress,
2059 Component,
2088 - resolvedProps,
2060 + props,
2061 renderLanes,
2062 );
2063 }
2064 } else if (Component !== undefined && Component !== null) {
2065 const $$typeof = Component.$$typeof;
2066 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2095 - const resolvedProps = disableDefaultPropsExceptForClasses
2096 - ? props
2097 - : resolveDefaultPropsOnNonClassComponent(Component, props);
2067 workInProgress.tag = ForwardRef;
2068 if (__DEV__) {
2069 workInProgress.type = Component =
@@ -2104,24 +2073,16 @@ function mountLazyComponent(
2073 null,
2074 workInProgress,
2075 Component,
2107 - resolvedProps,
2076 + props,
2077 renderLanes,
2078 );
2079 } else if ($$typeof === REACT_MEMO_TYPE) {
2111 - const resolvedProps = disableDefaultPropsExceptForClasses
2112 - ? props
2113 - : resolveDefaultPropsOnNonClassComponent(Component, props);
2080 workInProgress.tag = MemoComponent;
2081 return updateMemoComponent(
2082 null,
2083 workInProgress,
2084 Component,
2119 - disableDefaultPropsExceptForClasses
2120 - ? resolvedProps
2121 - : resolveDefaultPropsOnNonClassComponent(
2122 - Component.type,
2123 - resolvedProps,
2124 - ), // The inner type can have defaults too
2085 + props,
2086 renderLanes,
2087 );
2088 }
@@ -2198,22 +2159,6 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) {
2159 );
2160 }
2161
2201 - if (
2202 - !disableDefaultPropsExceptForClasses &&
2203 - Component.defaultProps !== undefined
2204 - ) {
2205 - const componentName = getComponentNameFromType(Component) || 'Unknown';
2206 -
2207 - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
2208 - console.error(
2209 - '%s: Support for defaultProps will be removed from function components ' +
2210 - 'in a future major release. Use JavaScript default parameters instead.',
2211 - componentName,
2212 - );
2213 - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
2214 - }
2215 - }
2216 -
2162 if (typeof Component.getDerivedStateFromProps === 'function') {
2163 const componentName = getComponentNameFromType(Component) || 'Unknown';
2164
@@ -4175,17 +4120,11 @@ function beginWork(
4120 }
4121 case FunctionComponent: {
4122 const Component = workInProgress.type;
4178 - const unresolvedProps = workInProgress.pendingProps;
4179 - const resolvedProps =
4180 - disableDefaultPropsExceptForClasses ||
4181 - workInProgress.elementType === Component
4182 - ? unresolvedProps
4183 - : resolveDefaultPropsOnNonClassComponent(Component, unresolvedProps);
4123 return updateFunctionComponent(
4124 current,
4125 workInProgress,
4126 Component,
4188 - resolvedProps,
4127 + workInProgress.pendingProps,
4128 renderLanes,
4129 );
4130 }
@@ -4226,18 +4165,11 @@ function beginWork(
4165 case HostPortal:
4166 return updatePortalComponent(current, workInProgress, renderLanes);
4167 case ForwardRef: {
4229 - const type = workInProgress.type;
4230 - const unresolvedProps = workInProgress.pendingProps;
4231 - const resolvedProps =
4232 - disableDefaultPropsExceptForClasses ||
4233 - workInProgress.elementType === type
4234 - ? unresolvedProps
4235 - : resolveDefaultPropsOnNonClassComponent(type, unresolvedProps);
4168 return updateForwardRef(
4169 current,
4170 workInProgress,
4239 - type,
4240 - resolvedProps,
4171 + workInProgress.type,
4172 + workInProgress.pendingProps,
4173 renderLanes,
4174 );
4175 }
@@ -4252,20 +4184,11 @@ function beginWork(
4184 case ContextConsumer:
4185 return updateContextConsumer(current, workInProgress, renderLanes);
4186 case MemoComponent: {
4255 - const type = workInProgress.type;
4256 - const unresolvedProps = workInProgress.pendingProps;
4257 - // Resolve outer props first, then resolve inner props.
4258 - let resolvedProps = disableDefaultPropsExceptForClasses
4259 - ? unresolvedProps
4260 - : resolveDefaultPropsOnNonClassComponent(type, unresolvedProps);
4261 - resolvedProps = disableDefaultPropsExceptForClasses
4262 - ? resolvedProps
4263 - : resolveDefaultPropsOnNonClassComponent(type.type, resolvedProps);
4187 return updateMemoComponent(
4188 current,
4189 workInProgress,
4267 - type,
4268 - resolvedProps,
4190 + workInProgress.type,
4191 + workInProgress.pendingProps,
4192 renderLanes,
4193 );
4194 }
packages/react-reconciler/src/ReactFiberClassComponent.js
+1 -7
@@ -20,7 +20,6 @@ import {
20 import {
21 disableLegacyContext,
22 enableSchedulingProfiler,
23 - disableDefaultPropsExceptForClasses,
23 } from 'shared/ReactFeatureFlags';
24 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
25 import {get as getInstance, set as setInstance} from 'shared/ReactInstanceMap';
@@ -1214,12 +1213,7 @@ export function resolveClassComponentProps(
1213
1214 // Resolve default props.
1215 const defaultProps = Component.defaultProps;
1217 - if (
1218 - defaultProps &&
1219 - // If disableDefaultPropsExceptForClasses is true, we always resolve
1220 - // default props here in the reconciler, rather than in the JSX runtime.
1221 - (disableDefaultPropsExceptForClasses || !alreadyResolvedDefaultProps)
1222 - ) {
1216 + if (defaultProps) {
1217 // We may have already copied the props object above to remove ref. If so,
1218 // we can modify that. Otherwise, copy the props object with Object.assign.
1219 if (newProps === baseProps) {
packages/react-reconciler/src/ReactFiberLazyComponent.js deleted
-34
@@ -1,34 +0,0 @@
1 -/**
2 - * Copyright (c) Meta Platforms, Inc. and 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 - * @flow
8 - */
9 -
10 -import assign from 'shared/assign';
11 -import {disableDefaultPropsExceptForClasses} from 'shared/ReactFeatureFlags';
12 -
13 -export function resolveDefaultPropsOnNonClassComponent(
14 - Component: any,
15 - baseProps: Object,
16 -): Object {
17 - if (disableDefaultPropsExceptForClasses) {
18 - // Support for defaultProps is removed in React 19 for all types
19 - // except classes.
20 - return baseProps;
21 - }
22 - if (Component && Component.defaultProps) {
23 - // Resolve default props. Taken from ReactElement
24 - const props = assign({}, baseProps);
25 - const defaultProps = Component.defaultProps;
26 - for (const propName in defaultProps) {
27 - if (props[propName] === undefined) {
28 - props[propName] = defaultProps[propName];
29 - }
30 - }
31 - return props;
32 - }
33 - return baseProps;
34 -}
packages/react-reconciler/src/ReactFiberWorkLoop.js
+2 -17
@@ -46,7 +46,6 @@ import {
46 alwaysThrottleRetries,
47 enableInfiniteRenderLoopDetection,
48 disableLegacyMode,
49 - disableDefaultPropsExceptForClasses,
49 enableComponentPerformanceTrack,
50 enableYieldingBeforePassive,
51 enableThrottledScheduling,
@@ -349,7 +348,6 @@ import {
348 getSuspenseHandler,
349 getShellBoundary,
350 } from './ReactFiberSuspenseContext';
352 -import {resolveDefaultPropsOnNonClassComponent} from './ReactFiberLazyComponent';
351 import {resetChildReconcilerOnUnwind} from './ReactChildFiber';
352 import {
353 ensureRootIsScheduled,
@@ -2858,12 +2856,6 @@ function replayBeginWork(unitOfWork: Fiber): null | Fiber {
2856 // could maybe use this as an opportunity to say `use` doesn't work with
2857 // `defaultProps` :)
2858 const Component = unitOfWork.type;
2861 - const unresolvedProps = unitOfWork.pendingProps;
2862 - const resolvedProps =
2863 - disableDefaultPropsExceptForClasses ||
2864 - unitOfWork.elementType === Component
2865 - ? unresolvedProps
2866 - : resolveDefaultPropsOnNonClassComponent(Component, unresolvedProps);
2859 let context: any;
2860 if (!disableLegacyContext) {
2861 const unmaskedContext = getUnmaskedContext(unitOfWork, Component, true);
@@ -2872,7 +2864,7 @@ function replayBeginWork(unitOfWork: Fiber): null | Fiber {
2864 next = replayFunctionComponent(
2865 current,
2866 unitOfWork,
2875 - resolvedProps,
2867 + unitOfWork.pendingProps,
2868 Component,
2869 context,
2870 workInProgressRootRenderLanes,
@@ -2885,17 +2877,10 @@ function replayBeginWork(unitOfWork: Fiber): null | Fiber {
2877 // could maybe use this as an opportunity to say `use` doesn't work with
2878 // `defaultProps` :)
2879 const Component = unitOfWork.type.render;
2888 - const unresolvedProps = unitOfWork.pendingProps;
2889 - const resolvedProps =
2890 - disableDefaultPropsExceptForClasses ||
2891 - unitOfWork.elementType === Component
2892 - ? unresolvedProps
2893 - : resolveDefaultPropsOnNonClassComponent(Component, unresolvedProps);
2894 -
2880 next = replayFunctionComponent(
2881 current,
2882 unitOfWork,
2898 - resolvedProps,
2883 + unitOfWork.pendingProps,
2884 Component,
2885 unitOfWork.ref,
2886 workInProgressRootRenderLanes,
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
-417
@@ -701,64 +701,6 @@ describe('ReactLazy', () => {
701 expect(root).toMatchRenderedOutput('A3');
702 });
703
704 - // @gate !disableDefaultPropsExceptForClasses
705 - it('resolves defaultProps on the outer wrapper but warns', async () => {
706 - function T(props) {
707 - Scheduler.log(props.inner + ' ' + props.outer);
708 - return props.inner + ' ' + props.outer;
709 - }
710 - T.defaultProps = {inner: 'Hi'};
711 - const LazyText = lazy(() => fakeImport(T));
712 - LazyText.defaultProps = {outer: 'Bye'};
713 - assertConsoleErrorDev(
714 - [
715 - 'It is not supported to assign `defaultProps` to ' +
716 - 'a lazy component import. Either specify them where the component ' +
717 - 'is defined, or create a wrapping component around it.',
718 - ],
719 - {withoutStack: true},
720 - );
721 -
722 - const root = ReactTestRenderer.create(
723 - <Suspense fallback={<Text text="Loading..." />}>
724 - <LazyText />
725 - </Suspense>,
726 - {
727 - unstable_isConcurrent: true,
728 - },
729 - );
730 -
731 - await waitForAll(['Loading...']);
732 - expect(root).not.toMatchRenderedOutput('Hi Bye');
733 -
734 - await act(() => resolveFakeImport(T));
735 - assertLog(['Hi Bye']);
736 - assertConsoleErrorDev([
737 - 'T: Support for defaultProps ' +
738 - 'will be removed from function components in a future major ' +
739 - 'release. Use JavaScript default parameters instead.\n' +
740 - ' in T (at **)',
741 - ]);
742 -
743 - expect(root).toMatchRenderedOutput('Hi Bye');
744 -
745 - root.update(
746 - <Suspense fallback={<Text text="Loading..." />}>
747 - <LazyText outer="World" />
748 - </Suspense>,
749 - );
750 - await waitForAll(['Hi World']);
751 - expect(root).toMatchRenderedOutput('Hi World');
752 -
753 - root.update(
754 - <Suspense fallback={<Text text="Loading..." />}>
755 - <LazyText inner="Friends" />
756 - </Suspense>,
757 - );
758 - await waitForAll(['Friends Bye']);
759 - expect(root).toMatchRenderedOutput('Friends Bye');
760 - });
761 -
704 it('throws with a useful error when wrapping invalid type with lazy()', async () => {
705 const BadLazy = lazy(() => fakeImport(42));
706
@@ -1112,48 +1054,6 @@ describe('ReactLazy', () => {
1054 );
1055 });
1056
1115 - // @gate !disableDefaultPropsExceptForClasses
1116 - it('resolves props for function component with defaultProps', async () => {
1117 - function Add(props) {
1118 - expect(props.innerWithDefault).toBe(42);
1119 - return props.inner + props.outer;
1120 - }
1121 - Add.defaultProps = {
1122 - innerWithDefault: 42,
1123 - };
1124 - const LazyAdd = lazy(() => fakeImport(Add));
1125 - const root = ReactTestRenderer.create(
1126 - <Suspense fallback={<Text text="Loading..." />}>
1127 - <LazyAdd inner="2" outer="2" />
1128 - </Suspense>,
1129 - {
1130 - unstable_isConcurrent: true,
1131 - },
1132 - );
1133 -
1134 - await waitForAll(['Loading...']);
1135 - expect(root).not.toMatchRenderedOutput('22');
1136 -
1137 - // Mount
1138 - await act(() => resolveFakeImport(Add));
1139 -
1140 - assertConsoleErrorDev([
1141 - 'Add: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.\n' +
1142 - ' in Add (at **)',
1143 - ]);
1144 -
1145 - expect(root).toMatchRenderedOutput('22');
1146 -
1147 - // Update
1148 - root.update(
1149 - <Suspense fallback={<Text text="Loading..." />}>
1150 - <LazyAdd inner={false} outer={false} />
1151 - </Suspense>,
1152 - );
1153 - await waitForAll([]);
1154 - expect(root).toMatchRenderedOutput('0');
1155 - });
1156 -
1057 it('resolves props for function component without defaultProps', async () => {
1058 function Add(props) {
1059 return props.inner + props.outer;
@@ -1258,44 +1158,6 @@ describe('ReactLazy', () => {
1158 expect(root).toMatchRenderedOutput('0');
1159 });
1160
1261 - // @gate !disableDefaultPropsExceptForClasses
1262 - it('resolves props for forwardRef component with defaultProps', async () => {
1263 - const Add = React.forwardRef((props, ref) => {
1264 - expect(props.innerWithDefault).toBe(42);
1265 - return props.inner + props.outer;
1266 - });
1267 - Add.displayName = 'Add';
1268 - Add.defaultProps = {
1269 - innerWithDefault: 42,
1270 - };
1271 - const LazyAdd = lazy(() => fakeImport(Add));
1272 - const root = ReactTestRenderer.create(
1273 - <Suspense fallback={<Text text="Loading..." />}>
1274 - <LazyAdd inner="2" outer="2" />
1275 - </Suspense>,
1276 - {
1277 - unstable_isConcurrent: true,
1278 - },
1279 - );
1280 -
1281 - await waitForAll(['Loading...']);
1282 - expect(root).not.toMatchRenderedOutput('22');
1283 -
1284 - // Mount
1285 - await act(() => resolveFakeImport(Add));
1286 -
1287 - expect(root).toMatchRenderedOutput('22');
1288 -
1289 - // Update
1290 - root.update(
1291 - <Suspense fallback={<Text text="Loading..." />}>
1292 - <LazyAdd inner={false} outer={false} />
1293 - </Suspense>,
1294 - );
1295 - await waitForAll([]);
1296 - expect(root).toMatchRenderedOutput('0');
1297 - });
1298 -
1161 it('resolves props for forwardRef component without defaultProps', async () => {
1162 const Add = React.forwardRef((props, ref) => {
1163 return props.inner + props.outer;
@@ -1330,51 +1192,6 @@ describe('ReactLazy', () => {
1192 expect(root).toMatchRenderedOutput('0');
1193 });
1194
1333 - // @gate !disableDefaultPropsExceptForClasses
1334 - it('resolves props for outer memo component with defaultProps', async () => {
1335 - let Add = props => {
1336 - expect(props.innerWithDefault).toBe(42);
1337 - return props.inner + props.outer;
1338 - };
1339 - Add = React.memo(Add);
1340 - Add.defaultProps = {
1341 - innerWithDefault: 42,
1342 - };
1343 - const LazyAdd = lazy(() => fakeImport(Add));
1344 - const root = ReactTestRenderer.create(
1345 - <Suspense fallback={<Text text="Loading..." />}>
1346 - <LazyAdd inner="2" outer="2" />
1347 - </Suspense>,
1348 - {
1349 - unstable_isConcurrent: true,
1350 - },
1351 - );
1352 -
1353 - await waitForAll(['Loading...']);
1354 - expect(root).not.toMatchRenderedOutput('22');
1355 -
1356 - // Mount
1357 - await act(() => resolveFakeImport(Add));
1358 -
1359 - assertConsoleErrorDev(
1360 - [
1361 - 'Add: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.',
1362 - ],
1363 - {withoutStack: true},
1364 - );
1365 -
1366 - expect(root).toMatchRenderedOutput('22');
1367 -
1368 - // Update
1369 - root.update(
1370 - <Suspense fallback={<Text text="Loading..." />}>
1371 - <LazyAdd inner={false} outer={false} />
1372 - </Suspense>,
1373 - );
1374 - await waitForAll([]);
1375 - expect(root).toMatchRenderedOutput('0');
1376 - });
1377 -
1195 it('resolves props for outer memo component without defaultProps', async () => {
1196 let Add = props => {
1197 return props.inner + props.outer;
@@ -1408,52 +1225,6 @@ describe('ReactLazy', () => {
1225 expect(root).toMatchRenderedOutput('0');
1226 });
1227
1411 - // @gate !disableDefaultPropsExceptForClasses
1412 - it('resolves props for inner memo component with defaultProps', async () => {
1413 - const Add = props => {
1414 - expect(props.innerWithDefault).toBe(42);
1415 - return props.inner + props.outer;
1416 - };
1417 - Add.displayName = 'Add';
1418 - Add.defaultProps = {
1419 - innerWithDefault: 42,
1420 - };
1421 - const MemoAdd = React.memo(Add);
1422 - const LazyAdd = lazy(() => fakeImport(MemoAdd));
1423 - const root = ReactTestRenderer.create(
1424 - <Suspense fallback={<Text text="Loading..." />}>
1425 - <LazyAdd inner="2" outer="2" />
1426 - </Suspense>,
1427 - {
1428 - unstable_isConcurrent: true,
1429 - },
1430 - );
1431 -
1432 - await waitForAll(['Loading...']);
1433 - expect(root).not.toMatchRenderedOutput('22');
1434 -
1435 - // Mount
1436 - await act(() => resolveFakeImport(MemoAdd));
1437 -
1438 - assertConsoleErrorDev(
1439 - [
1440 - 'Add: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
1441 - ],
1442 - {withoutStack: true},
1443 - );
1444 -
1445 - expect(root).toMatchRenderedOutput('22');
1446 -
1447 - // Update
1448 - root.update(
1449 - <Suspense fallback={<Text text="Loading..." />}>
1450 - <LazyAdd inner={false} outer={false} />
1451 - </Suspense>,
1452 - );
1453 - await waitForAll([]);
1454 - expect(root).toMatchRenderedOutput('0');
1455 - });
1456 -
1228 it('resolves props for inner memo component without defaultProps', async () => {
1229 const Add = props => {
1230 return props.inner + props.outer;
@@ -1487,50 +1258,6 @@ describe('ReactLazy', () => {
1258 expect(root).toMatchRenderedOutput('0');
1259 });
1260
1490 - // @gate !disableDefaultPropsExceptForClasses
1491 - it('uses outer resolved props on memo', async () => {
1492 - let T = props => {
1493 - return <Text text={props.text} />;
1494 - };
1495 - T.defaultProps = {
1496 - text: 'Inner default text',
1497 - };
1498 - T = React.memo(T);
1499 - const LazyText = lazy(() => fakeImport(T));
1500 - const root = ReactTestRenderer.create(
1501 - <Suspense fallback={<Text text="Loading..." />}>
1502 - <LazyText />
1503 - </Suspense>,
1504 - {
1505 - unstable_isConcurrent: true,
1506 - },
1507 - );
1508 -
1509 - await waitForAll(['Loading...']);
1510 - expect(root).not.toMatchRenderedOutput('Inner default text');
1511 -
1512 - // Mount
1513 - await act(() => resolveFakeImport(T));
1514 - assertLog(['Inner default text']);
1515 - assertConsoleErrorDev(
1516 - [
1517 - 'T: Support for defaultProps will be removed from function components in a future major release. ' +
1518 - 'Use JavaScript default parameters instead.',
1519 - ],
1520 - {withoutStack: true},
1521 - );
1522 - expect(root).toMatchRenderedOutput('Inner default text');
1523 -
1524 - // Update
1525 - root.update(
1526 - <Suspense fallback={<Text text="Loading..." />}>
1527 - <LazyText text={null} />
1528 - </Suspense>,
1529 - );
1530 - await waitForAll([null]);
1531 - expect(root).toMatchRenderedOutput(null);
1532 - });
1533 -
1261 it('includes lazy-loaded component in warning stack', async () => {
1262 const Foo = props => <div>{[<Text text="A" />, <Text text="B" />]}</div>;
1263 const LazyFoo = lazy(() => {
@@ -1614,150 +1341,6 @@ describe('ReactLazy', () => {
1341 expect(ref.current).not.toBe(null);
1342 });
1343
1617 - // Regression test for #14310
1618 - // @gate !disableDefaultPropsExceptForClasses
1619 - it('supports defaultProps defined on the memo() return value', async () => {
1620 - const Add = React.memo(props => {
1621 - return props.inner + props.outer;
1622 - });
1623 - Add.defaultProps = {
1624 - inner: 2,
1625 - };
1626 - const LazyAdd = lazy(() => fakeImport(Add));
1627 - const root = ReactTestRenderer.create(
1628 - <Suspense fallback={<Text text="Loading..." />}>
1629 - <LazyAdd outer={2} />
1630 - </Suspense>,
1631 - {
1632 - unstable_isConcurrent: true,
1633 - },
1634 - );
1635 - await waitForAll(['Loading...']);
1636 - expect(root).not.toMatchRenderedOutput('4');
1637 -
1638 - // Mount
1639 - await act(() => resolveFakeImport(Add));
1640 - assertConsoleErrorDev(
1641 - [
1642 - 'Unknown: Support for defaultProps will be removed from memo components in a future major release. ' +
1643 - 'Use JavaScript default parameters instead.',
1644 - ],
1645 - {withoutStack: true},
1646 - );
1647 - expect(root).toMatchRenderedOutput('4');
1648 -
1649 - // Update (shallowly equal)
1650 - root.update(
1651 - <Suspense fallback={<Text text="Loading..." />}>
1652 - <LazyAdd outer={2} />
1653 - </Suspense>,
1654 - );
1655 - await waitForAll([]);
1656 - expect(root).toMatchRenderedOutput('4');
1657 -
1658 - // Update
1659 - root.update(
1660 - <Suspense fallback={<Text text="Loading..." />}>
1661 - <LazyAdd outer={3} />
1662 - </Suspense>,
1663 - );
1664 - await waitForAll([]);
1665 - expect(root).toMatchRenderedOutput('5');
1666 -
1667 - // Update (shallowly equal)
1668 - root.update(
1669 - <Suspense fallback={<Text text="Loading..." />}>
1670 - <LazyAdd outer={3} />
1671 - </Suspense>,
1672 - );
1673 - await waitForAll([]);
1674 - expect(root).toMatchRenderedOutput('5');
1675 -
1676 - // Update (explicit props)
1677 - root.update(
1678 - <Suspense fallback={<Text text="Loading..." />}>
1679 - <LazyAdd outer={1} inner={1} />
1680 - </Suspense>,
1681 - );
1682 - await waitForAll([]);
1683 - expect(root).toMatchRenderedOutput('2');
1684 -
1685 - // Update (explicit props, shallowly equal)
1686 - root.update(
1687 - <Suspense fallback={<Text text="Loading..." />}>
1688 - <LazyAdd outer={1} inner={1} />
1689 - </Suspense>,
1690 - );
1691 - await waitForAll([]);
1692 - expect(root).toMatchRenderedOutput('2');
1693 -
1694 - // Update
1695 - root.update(
1696 - <Suspense fallback={<Text text="Loading..." />}>
1697 - <LazyAdd outer={1} />
1698 - </Suspense>,
1699 - );
1700 - await waitForAll([]);
1701 - expect(root).toMatchRenderedOutput('3');
1702 - });
1703 -
1704 - // @gate !disableDefaultPropsExceptForClasses
1705 - it('merges defaultProps in the correct order', async () => {
1706 - let Add = React.memo(props => {
1707 - return props.inner + props.outer;
1708 - });
1709 - Add.defaultProps = {
1710 - inner: 100,
1711 - };
1712 - Add = React.memo(Add);
1713 - Add.defaultProps = {
1714 - inner: 2,
1715 - outer: 0,
1716 - };
1717 - const LazyAdd = lazy(() => fakeImport(Add));
1718 - const root = ReactTestRenderer.create(
1719 - <Suspense fallback={<Text text="Loading..." />}>
1720 - <LazyAdd outer={2} />
1721 - </Suspense>,
1722 - {
1723 - unstable_isConcurrent: true,
1724 - },
1725 - );
1726 - await waitForAll(['Loading...']);
1727 - expect(root).not.toMatchRenderedOutput('4');
1728 -
1729 - // Mount
1730 - await act(() => resolveFakeImport(Add));
1731 - assertConsoleErrorDev(
1732 - [
1733 - 'Memo: Support for defaultProps will be removed from memo components in a future major release. ' +
1734 - 'Use JavaScript default parameters instead.',
1735 - 'Unknown: Support for defaultProps will be removed from memo components in a future major release. ' +
1736 - 'Use JavaScript default parameters instead.',
1737 - ],
1738 - {withoutStack: true},
1739 - );
1740 - expect(root).toMatchRenderedOutput('4');
1741 -
1742 - // Update
1743 - root.update(
1744 - <Suspense fallback={<Text text="Loading..." />}>
1745 - <LazyAdd outer={3} />
1746 - </Suspense>,
1747 - );
1748 - await waitForAll([]);
1749 - expect(root).toMatchRenderedOutput('5');
1750 -
1751 - // Update
1752 - root.update(
1753 - <Suspense fallback={<Text text="Loading..." />}>
1754 - <LazyAdd />
1755 - </Suspense>,
1756 - );
1757 - await waitForAll([]);
1758 - expect(root).toMatchRenderedOutput('2');
1759 - });
1760 -
1344 it('should error with a component stack naming the resolved component', async () => {
1345 let componentStackMessage;
1346
packages/react-reconciler/src/__tests__/ReactMemo-test.js
-111
@@ -373,77 +373,6 @@ describe('memo', () => {
373 expect(ReactNoop).toMatchRenderedOutput(<span prop="1!" />);
374 });
375
376 - // @gate !disableDefaultPropsExceptForClasses
377 - it('supports defaultProps defined on the memo() return value', async () => {
378 - function Counter({a, b, c, d, e}) {
379 - return <Text text={a + b + c + d + e} />;
380 - }
381 - Counter.defaultProps = {
382 - a: 1,
383 - };
384 - // Note! We intentionally use React.memo() rather than the injected memo().
385 - // This tests a synchronous chain of React.memo() without lazy() in the middle.
386 - Counter = React.memo(Counter);
387 - Counter.defaultProps = {
388 - b: 2,
389 - };
390 - Counter = React.memo(Counter);
391 - Counter = React.memo(Counter); // Layer without defaultProps
392 - Counter.defaultProps = {
393 - c: 3,
394 - };
395 - Counter = React.memo(Counter);
396 - Counter.defaultProps = {
397 - d: 4,
398 - };
399 - // The final layer uses memo() from test fixture (which might be lazy).
400 - Counter = memo(Counter);
401 -
402 - await act(() => {
403 - ReactNoop.render(
404 - <Suspense fallback={<Text text="Loading..." />}>
405 - <Counter e={5} />
406 - </Suspense>,
407 - );
408 - });
409 - assertLog(['Loading...', 15]);
410 - if (label === 'lazy') {
411 - assertConsoleErrorDev(
412 - [
413 - 'Counter: Support for defaultProps will be removed from memo components in a future major release. ' +
414 - 'Use JavaScript default parameters instead.',
415 - ],
416 - {withoutStack: true},
417 - );
418 - } else {
419 - assertConsoleErrorDev([
420 - 'Counter: Support for defaultProps will be removed from memo components in a future major release. ' +
421 - 'Use JavaScript default parameters instead.\n' +
422 - ' in Indirection (at **)',
423 - ]);
424 - }
425 -
426 - expect(ReactNoop).toMatchRenderedOutput(<span prop={15} />);
427 -
428 - // Should bail out because props have not changed
429 - ReactNoop.render(
430 - <Suspense>
431 - <Counter e={5} />
432 - </Suspense>,
433 - );
434 - await waitForAll([]);
435 - expect(ReactNoop).toMatchRenderedOutput(<span prop={15} />);
436 -
437 - // Should update because count prop changed
438 - ReactNoop.render(
439 - <Suspense>
440 - <Counter e={10} />
441 - </Suspense>,
442 - );
443 - await waitForAll([20]);
444 - expect(ReactNoop).toMatchRenderedOutput(<span prop={20} />);
445 - });
446 -
376 it('warns if the first argument is undefined', () => {
377 memo();
378 assertConsoleErrorDev(
@@ -466,46 +395,6 @@ describe('memo', () => {
395 );
396 });
397
469 - // @gate !disableDefaultPropsExceptForClasses
470 - it('handles nested defaultProps declarations', async () => {
471 - function Inner(props) {
472 - return props.inner + props.middle + props.outer;
473 - }
474 - Inner.defaultProps = {inner: 1};
475 - const Middle = React.memo(Inner);
476 - Middle.defaultProps = {middle: 10};
477 - const Outer = React.memo(Middle);
478 - Outer.defaultProps = {outer: 100};
479 -
480 - const root = ReactNoop.createRoot();
481 - await act(() => {
482 - root.render(
483 - <div>
484 - <Outer />
485 - </div>,
486 - );
487 - });
488 - assertConsoleErrorDev(
489 - [
490 - 'Inner: ' +
491 - 'Support for defaultProps will be removed from memo components in a future major release. ' +
492 - 'Use JavaScript default parameters instead.',
493 - ],
494 - {withoutStack: true},
495 - );
496 - expect(root).toMatchRenderedOutput(<div>111</div>);
497 -
498 - await act(async () => {
499 - root.render(
500 - <div>
501 - <Outer inner="2" middle="3" outer="4" />
502 - </div>,
503 - );
504 - await waitForAll([]);
505 - });
506 - expect(root).toMatchRenderedOutput(<div>234</div>);
507 - });
508 -
398 it('does not drop lower priority state updates when bailing out at higher pri (simple)', async () => {
399 const {useState} = React;
400
packages/react-server/src/ReactFizzServer.js
+3 -57
@@ -178,7 +178,6 @@ import {
178 enableScopeAPI,
179 enablePostpone,
180 enableHalt,
181 - disableDefaultPropsExceptForClasses,
181 enableAsyncIterableChildren,
182 enableViewTransition,
183 enableFizzBlockingRender,
@@ -2399,12 +2398,7 @@ export function resolveClassComponentProps(
2398
2399 // Resolve default props.
2400 const defaultProps = Component.defaultProps;
2402 - if (
2403 - defaultProps &&
2404 - // If disableDefaultPropsExceptForClasses is true, we always resolve
2405 - // default props here, rather than in the JSX runtime.
2406 - disableDefaultPropsExceptForClasses
2407 - ) {
2401 + if (defaultProps) {
2402 // We may have already copied the props object above to remove ref. If so,
2403 // we can modify that. Otherwise, copy the props object with Object.assign.
2404 if (newProps === baseProps) {
@@ -2453,7 +2447,6 @@ const didWarnAboutContextTypes: {[string]: boolean} = {};
2447 const didWarnAboutContextTypeOnFunctionComponent: {[string]: boolean} = {};
2448 const didWarnAboutGetDerivedStateOnFunctionComponent: {[string]: boolean} = {};
2449 let didWarnAboutReassigningProps = false;
2456 -const didWarnAboutDefaultPropsOnFunctionComponent: {[string]: boolean} = {};
2450 let didWarnAboutGenerators = false;
2451 let didWarnAboutMaps = false;
2452
@@ -2610,22 +2603,6 @@ function validateFunctionComponentInDev(Component: any): void {
2603 );
2604 }
2605
2613 - if (
2614 - !disableDefaultPropsExceptForClasses &&
2615 - Component.defaultProps !== undefined
2616 - ) {
2617 - const componentName = getComponentNameFromType(Component) || 'Unknown';
2618 -
2619 - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
2620 - console.error(
2621 - '%s: Support for defaultProps will be removed from function components ' +
2622 - 'in a future major release. Use JavaScript default parameters instead.',
2623 - componentName,
2624 - );
2625 - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
2626 - }
2627 - }
2628 -
2606 if (typeof Component.getDerivedStateFromProps === 'function') {
2607 const componentName = getComponentNameFromType(Component) || 'Unknown';
2608
@@ -2655,29 +2632,6 @@ function validateFunctionComponentInDev(Component: any): void {
2632 }
2633 }
2634
2658 -function resolveDefaultPropsOnNonClassComponent(
2659 - Component: any,
2660 - baseProps: Object,
2661 -): Object {
2662 - if (disableDefaultPropsExceptForClasses) {
2663 - // Support for defaultProps is removed in React 19 for all types
2664 - // except classes.
2665 - return baseProps;
2666 - }
2667 - if (Component && Component.defaultProps) {
2668 - // Resolve default props. Taken from ReactElement
2669 - const props = assign({}, baseProps);
2670 - const defaultProps = Component.defaultProps;
2671 - for (const propName in defaultProps) {
2672 - if (props[propName] === undefined) {
2673 - props[propName] = defaultProps[propName];
2674 - }
2675 - }
2676 - return props;
2677 - }
2678 - return baseProps;
2679 -}
2680 -
2635 function renderForwardRef(
2636 request: Request,
2637 task: Task,
@@ -2735,11 +2689,7 @@ function renderMemo(
2689 ref: any,
2690 ): void {
2691 const innerType = type.type;
2738 - const resolvedProps = resolveDefaultPropsOnNonClassComponent(
2739 - innerType,
2740 - props,
2741 - );
2742 - renderElement(request, task, keyPath, innerType, resolvedProps, ref);
2692 + renderElement(request, task, keyPath, innerType, props, ref);
2693 }
2694
2695 function renderContextConsumer(
@@ -2819,11 +2769,7 @@ function renderLazyComponent(
2769 // eslint-disable-next-line no-throw-literal
2770 throw null;
2771 }
2822 - const resolvedProps = resolveDefaultPropsOnNonClassComponent(
2823 - Component,
2824 - props,
2825 - );
2826 - renderElement(request, task, keyPath, Component, resolvedProps, ref);
2772 + renderElement(request, task, keyPath, Component, props, ref);
2773 }
2774
2775 function renderActivity(
packages/react/src/ReactLazy.js
-31
@@ -10,7 +10,6 @@
10 import type {Wakeable, Thenable, ReactDebugInfo} from 'shared/ReactTypes';
11
12 import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';
13 -import {disableDefaultPropsExceptForClasses} from 'shared/ReactFeatureFlags';
13
14 const Uninitialized = -1;
15 const Pending = 0;
@@ -141,35 +140,5 @@ export function lazy<T>(
140 _init: lazyInitializer,
141 };
142
144 - if (!disableDefaultPropsExceptForClasses) {
145 - if (__DEV__) {
146 - // In production, this would just set it on the object.
147 - let defaultProps;
148 - // $FlowFixMe[prop-missing]
149 - Object.defineProperties(lazyType, {
150 - defaultProps: {
151 - configurable: true,
152 - get() {
153 - return defaultProps;
154 - },
155 - // $FlowFixMe[missing-local-annot]
156 - set(newDefaultProps) {
157 - console.error(
158 - 'It is not supported to assign `defaultProps` to ' +
159 - 'a lazy component import. Either specify them where the component ' +
160 - 'is defined, or create a wrapping component around it.',
161 - );
162 - defaultProps = newDefaultProps;
163 - // Match production behavior more closely:
164 - // $FlowFixMe[prop-missing]
165 - Object.defineProperty(lazyType, 'defaultProps', {
166 - enumerable: true,
167 - });
168 - },
169 - },
170 - });
171 - }
172 - }
173 -
143 return lazyType;
144 }
packages/react/src/__tests__/ReactElementClone-test.js
-22
@@ -291,28 +291,6 @@ describe('ReactElementClone', () => {
291 );
292 });
293
294 - // @gate !disableDefaultPropsExceptForClasses
295 - it('should normalize props with default values', () => {
296 - class Component extends React.Component {
297 - render() {
298 - return <span />;
299 - }
300 - }
301 - Component.defaultProps = {prop: 'testKey'};
302 -
303 - const instance = React.createElement(Component);
304 - const clonedInstance = React.cloneElement(instance, {prop: undefined});
305 - expect(clonedInstance.props.prop).toBe('testKey');
306 - const clonedInstance2 = React.cloneElement(instance, {prop: null});
307 - expect(clonedInstance2.props.prop).toBe(null);
308 -
309 - const instance2 = React.createElement(Component, {prop: 'newTestKey'});
310 - const cloneInstance3 = React.cloneElement(instance2, {prop: undefined});
311 - expect(cloneInstance3.props.prop).toBe('testKey');
312 - const cloneInstance4 = React.cloneElement(instance2, {});
313 - expect(cloneInstance4.props.prop).toBe('newTestKey');
314 - });
315 -
294 it('warns for keys for arrays of elements in rest args', async () => {
295 const root = ReactDOMClient.createRoot(document.createElement('div'));
296 await act(() => {
packages/react/src/__tests__/forwardRef-test.js
-39
@@ -76,45 +76,6 @@ describe('forwardRef', () => {
76 expect(ref.current).toBe(null);
77 });
78
79 - // @gate !disableDefaultPropsExceptForClasses
80 - it('should support defaultProps', async () => {
81 - function FunctionComponent({forwardedRef, optional, required}) {
82 - return (
83 - <div ref={forwardedRef}>
84 - {optional}
85 - {required}
86 - </div>
87 - );
88 - }
89 -
90 - const RefForwardingComponent = React.forwardRef(
91 - function NamedFunction(props, ref) {
92 - return <FunctionComponent {...props} forwardedRef={ref} />;
93 - },
94 - );
95 - RefForwardingComponent.defaultProps = {
96 - optional: 'default',
97 - };
98 -
99 - const ref = React.createRef();
100 -
101 - ReactNoop.render(
102 - <RefForwardingComponent ref={ref} optional="foo" required="bar" />,
103 - );
104 - await waitForAll([]);
105 - expect(ref.current.children).toEqual([
106 - {text: 'foo', hidden: false},
107 - {text: 'bar', hidden: false},
108 - ]);
109 -
110 - ReactNoop.render(<RefForwardingComponent ref={ref} required="foo" />);
111 - await waitForAll([]);
112 - expect(ref.current.children).toEqual([
113 - {text: 'default', hidden: false},
114 - {text: 'foo', hidden: false},
115 - ]);
116 - });
117 -
79 it('should warn if not provided a callback during creation', () => {
80 React.forwardRef(undefined);
81 assertConsoleErrorDev(
packages/react/src/jsx/ReactJSXElement.js
+2 -46
@@ -16,10 +16,7 @@ import {
16 } from 'shared/ReactSymbols';
17 import {checkKeyStringCoercion} from 'shared/CheckStringCoercion';
18 import isArray from 'shared/isArray';
19 -import {
20 - disableDefaultPropsExceptForClasses,
21 - ownerStackLimit,
22 -} from 'shared/ReactFeatureFlags';
19 +import {ownerStackLimit} from 'shared/ReactFeatureFlags';
20
21 const createTask =
22 // eslint-disable-next-line react-internal/no-production-logging
@@ -351,18 +348,6 @@ export function jsxProd(type, config, maybeKey) {
348 }
349 }
350
354 - if (!disableDefaultPropsExceptForClasses) {
355 - // Resolve default props
356 - if (type && type.defaultProps) {
357 - const defaultProps = type.defaultProps;
358 - for (const propName in defaultProps) {
359 - if (props[propName] === undefined) {
360 - props[propName] = defaultProps[propName];
361 - }
362 - }
363 - }
364 - }
365 -
351 return ReactElement(
352 type,
353 key,
@@ -598,18 +583,6 @@ function jsxDEVImpl(
583 }
584 }
585
601 - if (!disableDefaultPropsExceptForClasses) {
602 - // Resolve default props
603 - if (type && type.defaultProps) {
604 - const defaultProps = type.defaultProps;
605 - for (const propName in defaultProps) {
606 - if (props[propName] === undefined) {
607 - props[propName] = defaultProps[propName];
608 - }
609 - }
610 - }
611 - }
612 -
586 if (key) {
587 const displayName =
588 typeof type === 'function'
@@ -817,14 +790,6 @@ export function cloneElement(element, config, children) {
790 }
791
792 // Remaining properties override existing props
820 - let defaultProps;
821 - if (
822 - !disableDefaultPropsExceptForClasses &&
823 - element.type &&
824 - element.type.defaultProps
825 - ) {
826 - defaultProps = element.type.defaultProps;
827 - }
793 for (propName in config) {
794 if (
795 hasOwnProperty.call(config, propName) &&
@@ -843,16 +808,7 @@ export function cloneElement(element, config, children) {
808 // backwards compatibility.
809 !(propName === 'ref' && config.ref === undefined)
810 ) {
846 - if (
847 - !disableDefaultPropsExceptForClasses &&
848 - config[propName] === undefined &&
849 - defaultProps !== undefined
850 - ) {
851 - // Resolve default props
852 - props[propName] = defaultProps[propName];
853 - } else {
854 - props[propName] = config[propName];
855 - }
811 + props[propName] = config[propName];
812 }
813 }
814 }
packages/shared/ReactFeatureFlags.js
-3
@@ -37,9 +37,6 @@ export const favorSafetyOverHydrationPerf = true;
37 // Need to remove didTimeout argument from Scheduler before landing
38 export const disableSchedulerTimeoutInWorkLoop = false;
39
40 -// TODO: Land at Meta before removing.
41 -export const disableDefaultPropsExceptForClasses = true;
42 -
40 // -----------------------------------------------------------------------------
41 // Slated for removal in the future (significant effort)
42 //
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -33,7 +33,6 @@ export const {
33 // The rest of the flags are static for better dead code elimination.
34 export const disableClientCache = true;
35 export const disableCommentsAsDOMContainers = true;
36 -export const disableDefaultPropsExceptForClasses = true;
36 export const disableInputAttributeSyncing = false;
37 export const disableLegacyContext = false;
38 export const disableLegacyContextForFunctionComponents = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -18,7 +18,6 @@ import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
18 export const alwaysThrottleRetries = false;
19 export const disableClientCache = true;
20 export const disableCommentsAsDOMContainers = true;
21 -export const disableDefaultPropsExceptForClasses = true;
21 export const disableInputAttributeSyncing = false;
22 export const disableLegacyContext = true;
23 export const disableLegacyContextForFunctionComponents = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -89,7 +89,6 @@ export const disableLegacyMode = true;
89 export const disableLegacyContext = true;
90 export const disableLegacyContextForFunctionComponents = true;
91 export const enableReactTestRendererWarning = true;
92 -export const disableDefaultPropsExceptForClasses = true;
92
93 export const enableObjectFiber = false;
94
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-2
@@ -63,8 +63,6 @@ export const enableInfiniteRenderLoopDetection = false;
63 export const enableReactTestRendererWarning = false;
64 export const disableLegacyMode = true;
65
66 -export const disableDefaultPropsExceptForClasses = true;
67 -
66 export const renameElementSymbol = false;
67
68 export const enableObjectFiber = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -14,7 +14,6 @@
14 // with the __VARIANT__ set to `true`, and once set to `false`.
15
16 export const alwaysThrottleRetries = __VARIANT__;
17 -export const disableDefaultPropsExceptForClasses = __VARIANT__;
17 export const disableLegacyContextForFunctionComponents = __VARIANT__;
18 export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
19 export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -16,7 +16,6 @@ const dynamicFeatureFlags: DynamicFeatureFlags = require('ReactFeatureFlags');
16
17 export const {
18 alwaysThrottleRetries,
19 - disableDefaultPropsExceptForClasses,
19 disableLegacyContextForFunctionComponents,
20 disableSchedulerTimeoutInWorkLoop,
21 enableHiddenSubtreeInsertionEffectCleanup,