-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Default props not working in functional component #31247
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
Comments
The documentation may not be clear on this, but you have to mark the property as optional in your interface Props {
name: string;
optional?: string;
} |
That doesn't seem to match what the release notes say: export interface Props {
name: string;
}
// ...
function Greet({ name = "world" }: Props) {
return <div>Hello {name.toUpperCase()}!</div>;
} |
Making the prop optional also means that when you access the props outside of the component (in a test), the type system does not guarantee that the prop exists even though it will always exist. Example: const wrapper = shallow(<Test/>);
// optional is string | undefined instead of string
const optional = wrapper
.find(Component)
.props()
.optional; If |
With TypeScript 3.1 or above you should be able to write: export interface Props {
name: string;
}
function Greet(props: Props) {
return <div>Hello {props.name.toUpperCase()}!</div>;
}
Greet.defaultProps = {
name: "world",
} as Partial<Props>; // Good practice, without it you could use a number as default prop and TypeScript wouldn't complain…
const component = <Greet />; // no errors |
Is it a bug that using the default initializer feature does not work for default props? It seems like a regression given that the example given in the release notes does not work on the latest TypeScript version. |
@tbassetto The problem with that is that TS doesn't force you to actually provide a default value:
The other annoying thing is the fact that you have to do this in the first place: If I type All in all, TypeScripts JSX/React support right now seems to be in a weird not-quite-perfect" state, but running as if everything is fine (at least in my eyes - Mainly, I can't seem to find any solid notes on what currently is the "Official" way to do stateless React components in a type safe manner for 3.4.5). |
Although I see everyone referencing work arounds, I am unable to get any of them to work. I am on version 3.3.3 export interface Props {
shouldTruncateContent: boolean;
}
const Alert: React.FunctionComponent<Props> = ({
children,
shouldTruncateContent = false
}) => {
return (
<S.Content shouldTruncateContent={shouldTruncateContent} size="fill">
{children}
</S.Content>
);
};
Alert.defaultProps = {
shouldTruncateContent: false
} as Pick<Props, 'shouldTruncateContent'>;
export default Alert; Does anyone have any insight into why this still throws the error
|
@tomspeak Either my workaround or @Hotell's woraround (although this one makes all props optional). Tested on 3.5 with your sample code. |
You just need to make shouldTruncateContent: boolean; optional |
I am using this optional type everywhere. Why the down vote ? Could someone explain ? |
@ralexhassle, I can't explain the down votes, but I can explain that is certainly a correct way of typing a component's optional property. |
The purpose of the issue is that the props are not optional, but have a default value (therefore can be eluded when using the component). If you mark the prop optional with |
@RyanCavanaugh why has the bot closed this issue? Perhaps I missed it but I do not see an actual answer, despite lot of workarounds? PS: using TypeScript v4 |
You can do it in this way, here properties in Props are the optional parameter and further used in the component.
|
@lakhmeranikita The purpose of this issue is to avoid marking a prop type as optional. |
I was unable to get function default arguments or other proposals to type check properly. The only workable solution I was able to find is this: import React from "react";
type DefaultProps = { optionalProp: number };
type Props = {
requiredProp: "some_string" | "other_string";
} & DefaultProps;
export const BaseComponent = (props: Props) => {
const { requiredProp, optionalProp } = props;
return (
<div>
{requiredProp} {optionalProp}
</div>
);
};
BaseComponent.defaultProps = {
optionalProp: 0,
} as Partial<DefaultProps>;
const comp = <BaseComponent requiredProp="some_string" />; |
Any reason why this was closed? Still an issue on 4.1 |
@the-kenneth what was causing my issue was that I was typing my variable as React.FunctionalComponent.
Now if I declare button like this:
it works. Source: #27425 (comment) I still think it's a bug (people explain better in the issue above), but it might be something that works for you |
@AzureMarker two years later, have you found any fix ? because as you said, we should avoid marking a prop type as optional. |
@mo-alaa I'm not using TypeScript/React in my current projects. I think I just went with the defaultProps approach. |
TypeScript Version: 3.4.5
Search Terms:
react default props defaultProps functional component stateless
Code
Expected behavior:
According to the TypeScript 3.0 release notes, the
optional
prop should not be required inTest
as it has been defined with a default using the ES2015 default initializers feature inComponent
.Actual behavior:
The following compile error is thrown:
Playground Link:
Link
It doesn't look like the playground supports TSX.
Related Issues:
#27425
The text was updated successfully, but these errors were encountered: