DEV Community

Aurora
Aurora

Posted on • Edited on

Don't use Function Components, use Void Function Components

One thing you'll come across when using Typescript with React is giving types to your components.

Most places I've seen will use React.FC for this:

const MyButton: React.FC<MyButtonProps> = ({prop1, prop2}) => {
  //...
}
Enter fullscreen mode Exit fullscreen mode

And while React.FC is an actual type, most uses of it are incorrect.

This becomes clear when you look at its definition:

type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P> | undefined;
    contextTypes?: ValidationMap<any> | undefined;
    defaultProps?: Partial<P> | undefined;
    displayName?: string | undefined;
}
Enter fullscreen mode Exit fullscreen mode

The notable thing here is that props gets PropsWithChilren, which means that you component will be able to take children in adition to your other props you passed in.

On the other hand, there also exists Void Function Components or VFCs:

type VFC<P = {}> = VoidFunctionComponent<P>;

interface VoidFunctionComponent<P = {}> {
    (props: P, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    defaultProps?: Partial<P>;
    displayName?: string;
}
Enter fullscreen mode Exit fullscreen mode

The only difference between this and FC is that when you tell it that P is its props, it will use just that, and it won't add an aditional children props to the final type.

conclusion

If you have some sort of pannel component or an abstract component which takes in children to render, then yeah, React.FC is the type for those.

But if the component you have isn't meant to have any more children, like a custom button or a custom card or input or whatever else, then using React.VFC is more correct.

Top comments (3)

Collapse
 
obfusticatedcode profile image
Chisomo Kenneth Lungu

In the latest version of React. VoidFunctionComponent is now deprecated.

   /**
     * @deprecated - Equivalent with `React.FC`.
     */
    type VFC<P = {}> = VoidFunctionComponent<P>;

    /**
     * @deprecated - Equivalent with `React.FunctionComponent`.
     */
Enter fullscreen mode Exit fullscreen mode
Collapse
 
revelt profile image
Roy Revelt

Good article! Tiny thing, in sentence "then yeah, React.RC is the type for those", it was meant to be React.FC, not React.RC.

Collapse
 
aurora2500 profile image
Aurora

Fixed the typo, thanks!