-
Notifications
You must be signed in to change notification settings - Fork 46.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove defaultProps support (except for classes) #28733
Conversation
}); | ||
}, | ||
}, | ||
propTypes: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated, but I removed this warning entirely since propTypes
support has already been removed from the codebase.
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.
44a5b6c
to
41b4a69
Compare
if (props[propName] === undefined) { | ||
props[propName] = defaultProps[propName]; | ||
if (!disableDefaultPropsExceptForClasses) { | ||
// Resolve default props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be removed even when the flag is off? Because the resolution moves regardless?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I implemented the flag is that when it's off, it maintains the old behavior: props resolved during JSX. I did it that way to aid the roll out at Meta and reduce the risk the whole change gets reverted. Since there could be code that reads element.props
and expects the defaultProps
to already be there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So really the flag handles both moving the resolution and removing it for non-classes, I just didn't think it was worth creating two separate flags.
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 [48b4ecc](48b4ecc)
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 [48b4ecc](48b4ecc)
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 [48b4ecc](48b4ecc)
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.
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.
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.
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: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.