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,