Skip to content

Commit

Permalink
Remove defaultProps support (except for classes) (#28733)
Browse files Browse the repository at this point in the history
This removes defaultProps support for all component types except for
classes. We've chosen to continue supporting defaultProps for classes
because lots of older code relies on it, and unlike function components,
(which can use default params), there's no straightforward alternative.

By implication, it also removes support for setting defaultProps on
`React.lazy` wrapper. So this will not work:

```js
const MyClassComponent = React.lazy(() => import('./MyClassComponent'));
// MyClassComponent is not actually a class; it's a lazy wrapper. So
// defaultProps does not work.
MyClassComponent.defaultProps = { foo: 'bar' };
```

However, if you set the default props on the class itself, then it's
fine.

For classes, this change also moves where defaultProps are resolved.
Previously, defaultProps were resolved by the JSX runtime. This change
is only observable if you introspect a JSX element, which is relatively
rare but does happen.

In other words, previously `<ClassWithDefaultProp />.props.aDefaultProp`
would resolve to the default prop value, but now it does not.

DiffTrain build for commit 48b4ecc.
  • Loading branch information
acdlite committed Apr 4, 2024
1 parent c6a78b2 commit 2504236
Show file tree
Hide file tree
Showing 17 changed files with 525 additions and 274 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<db6ccf0f194d95b91555bdb488cc0fab>>
* @generated SignedSource<<3151ca79177b1e7b421f14db372bfd97>>
*/

"use strict";
Expand Down Expand Up @@ -13206,7 +13206,11 @@ if (__DEV__) {

var defaultProps = Component.defaultProps;

if (defaultProps && !alreadyResolvedDefaultProps) {
if (
defaultProps && // If disableDefaultPropsExceptForClasses is true, we always resolve
// default props here in the reconciler, rather than in the JSX runtime.
!alreadyResolvedDefaultProps
) {
newProps = assign({}, newProps, baseProps);

for (var propName in defaultProps) {
Expand All @@ -13219,10 +13223,7 @@ if (__DEV__) {
return newProps;
}

function resolveDefaultProps(Component, baseProps) {
// TODO: Remove support for default props for everything except class
// components, including setting default props on a lazy wrapper around a
// class type.
function resolveDefaultPropsOnNonClassComponent(Component, baseProps) {
if (Component && Component.defaultProps) {
// Resolve default props. Taken from ReactElement
var props = assign({}, baseProps);
Expand Down Expand Up @@ -14073,17 +14074,20 @@ if (__DEV__) {
}

{
if (Component.defaultProps !== undefined) {
var componentName = getComponentNameFromType(type) || "Unknown";
{
if (Component.defaultProps !== undefined) {
var componentName = getComponentNameFromType(type) || "Unknown";

if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
error(
"%s: Support for defaultProps will be removed from memo components " +
"in a future major release. Use JavaScript default parameters instead.",
componentName
);
if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
error(
"%s: Support for defaultProps will be removed from memo components " +
"in a future major release. Use JavaScript default parameters instead.",
componentName
);

didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
didWarnAboutDefaultPropsOnFunctionComponent[componentName] =
true;
}
}
}
}
Expand Down Expand Up @@ -15051,7 +15055,10 @@ if (__DEV__) {
renderLanes
);
} else {
var _resolvedProps = resolveDefaultProps(Component, props);
var _resolvedProps = resolveDefaultPropsOnNonClassComponent(
Component,
props
);

workInProgress.tag = FunctionComponent;

Expand All @@ -15073,7 +15080,10 @@ if (__DEV__) {
var $$typeof = Component.$$typeof;

if ($$typeof === REACT_FORWARD_REF_TYPE) {
var _resolvedProps2 = resolveDefaultProps(Component, props);
var _resolvedProps2 = resolveDefaultPropsOnNonClassComponent(
Component,
props
);

workInProgress.tag = ForwardRef;

Expand All @@ -15090,14 +15100,20 @@ if (__DEV__) {
renderLanes
);
} else if ($$typeof === REACT_MEMO_TYPE) {
var _resolvedProps3 = resolveDefaultProps(Component, props);
var _resolvedProps3 = resolveDefaultPropsOnNonClassComponent(
Component,
props
);

workInProgress.tag = MemoComponent;
return updateMemoComponent(
null,
workInProgress,
Component,
resolveDefaultProps(Component.type, _resolvedProps3), // The inner type can have defaults too
resolveDefaultPropsOnNonClassComponent(
Component.type,
_resolvedProps3
), // The inner type can have defaults too
renderLanes
);
}
Expand Down Expand Up @@ -16969,7 +16985,10 @@ if (__DEV__) {
var resolvedProps =
workInProgress.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
: resolveDefaultPropsOnNonClassComponent(
Component,
unresolvedProps
);
return updateFunctionComponent(
current,
workInProgress,
Expand Down Expand Up @@ -17028,7 +17047,7 @@ if (__DEV__) {
var _resolvedProps5 =
workInProgress.elementType === type
? _unresolvedProps2
: resolveDefaultProps(type, _unresolvedProps2);
: resolveDefaultPropsOnNonClassComponent(type, _unresolvedProps2);

return updateForwardRef(
current,
Expand Down Expand Up @@ -17058,9 +17077,15 @@ if (__DEV__) {
var _type = workInProgress.type;
var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.

var _resolvedProps6 = resolveDefaultProps(_type, _unresolvedProps3);
var _resolvedProps6 = resolveDefaultPropsOnNonClassComponent(
_type,
_unresolvedProps3
);

_resolvedProps6 = resolveDefaultProps(_type.type, _resolvedProps6);
_resolvedProps6 = resolveDefaultPropsOnNonClassComponent(
_type.type,
_resolvedProps6
);
return updateMemoComponent(
current,
workInProgress,
Expand Down Expand Up @@ -24265,7 +24290,10 @@ if (__DEV__) {
var resolvedProps =
unitOfWork.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
: resolveDefaultPropsOnNonClassComponent(
Component,
unresolvedProps
);
var context;

{
Expand Down Expand Up @@ -24299,7 +24327,10 @@ if (__DEV__) {
var _resolvedProps =
unitOfWork.elementType === _Component
? _unresolvedProps
: resolveDefaultProps(_Component, _unresolvedProps);
: resolveDefaultPropsOnNonClassComponent(
_Component,
_unresolvedProps
);

next = replayFunctionComponent(
current,
Expand Down Expand Up @@ -26792,7 +26823,7 @@ if (__DEV__) {
return root;
}

var ReactVersion = "19.0.0-canary-7222486b";
var ReactVersion = "19.0.0-canary-29bd6113";

// Might add PROFILE later.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<d22e4f68e4066f13b69d1eb196608c2c>>
* @generated SignedSource<<432e9d2dc4a6b45da0162dd89f63ecfc>>
*/

"use strict";
Expand Down Expand Up @@ -3541,7 +3541,7 @@ function resolveClassComponentProps(
}
return newProps;
}
function resolveDefaultProps(Component, baseProps) {
function resolveDefaultPropsOnNonClassComponent(Component, baseProps) {
if (Component && Component.defaultProps) {
baseProps = assign({}, baseProps);
Component = Component.defaultProps;
Expand Down Expand Up @@ -4957,7 +4957,7 @@ function beginWork(current, workInProgress, renderLanes) {
props,
renderLanes
)))
: ((props = resolveDefaultProps(current, props)),
: ((props = resolveDefaultPropsOnNonClassComponent(current, props)),
(workInProgress.tag = 0),
(workInProgress = updateFunctionComponent(
null,
Expand All @@ -4972,7 +4972,7 @@ function beginWork(current, workInProgress, renderLanes) {
((elementType = current.$$typeof),
elementType === REACT_FORWARD_REF_TYPE)
) {
props = resolveDefaultProps(current, props);
props = resolveDefaultPropsOnNonClassComponent(current, props);
workInProgress.tag = 11;
workInProgress = updateForwardRef(
null,
Expand All @@ -4983,13 +4983,13 @@ function beginWork(current, workInProgress, renderLanes) {
);
break a;
} else if (elementType === REACT_MEMO_TYPE) {
props = resolveDefaultProps(current, props);
props = resolveDefaultPropsOnNonClassComponent(current, props);
workInProgress.tag = 14;
workInProgress = updateMemoComponent(
null,
workInProgress,
current,
resolveDefaultProps(current.type, props),
resolveDefaultPropsOnNonClassComponent(current.type, props),
renderLanes
);
break a;
Expand All @@ -5009,7 +5009,7 @@ function beginWork(current, workInProgress, renderLanes) {
(elementType =
workInProgress.elementType === props
? elementType
: resolveDefaultProps(props, elementType)),
: resolveDefaultPropsOnNonClassComponent(props, elementType)),
updateFunctionComponent(
current,
workInProgress,
Expand Down Expand Up @@ -5115,7 +5115,7 @@ function beginWork(current, workInProgress, renderLanes) {
(elementType =
workInProgress.elementType === props
? elementType
: resolveDefaultProps(props, elementType)),
: resolveDefaultPropsOnNonClassComponent(props, elementType)),
updateForwardRef(
current,
workInProgress,
Expand Down Expand Up @@ -5198,8 +5198,14 @@ function beginWork(current, workInProgress, renderLanes) {
case 14:
return (
(props = workInProgress.type),
(elementType = resolveDefaultProps(props, workInProgress.pendingProps)),
(elementType = resolveDefaultProps(props.type, elementType)),
(elementType = resolveDefaultPropsOnNonClassComponent(
props,
workInProgress.pendingProps
)),
(elementType = resolveDefaultPropsOnNonClassComponent(
props.type,
elementType
)),
updateMemoComponent(
current,
workInProgress,
Expand Down Expand Up @@ -8106,7 +8112,7 @@ function replaySuspendedUnitOfWork(unitOfWork) {
unresolvedProps =
unitOfWork.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
: resolveDefaultPropsOnNonClassComponent(Component, unresolvedProps);
var context = isContextProvider(Component)
? previousContext
: contextStackCursor$1.current;
Expand All @@ -8126,7 +8132,7 @@ function replaySuspendedUnitOfWork(unitOfWork) {
unresolvedProps =
unitOfWork.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
: resolveDefaultPropsOnNonClassComponent(Component, unresolvedProps);
current = replayFunctionComponent(
current,
unitOfWork,
Expand Down Expand Up @@ -9210,7 +9216,7 @@ var devToolsConfig$jscomp$inline_995 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-canary-ffc2b014",
version: "19.0.0-canary-0689007c",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1185 = {
Expand Down Expand Up @@ -9241,7 +9247,7 @@ var internals$jscomp$inline_1185 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-ffc2b014"
reconcilerVersion: "19.0.0-canary-0689007c"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1186 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Loading

0 comments on commit 2504236

Please sign in to comment.