Why You Should Probably Think Twice About Using React.FC

React.FC is a commonly used type amongst Typescript + React programmers. However, there may be something you don’t know about the type that should sway you from using it…

React.FC provides an implicit definition of children.

This means that defining a component with React.FC causes it to implicitly take children of type ReactNode. Even if your component doesn’t allow children, using React.FC opens your component’s props to it:


// An example of React.FC and implied children
const Foo: React.FC = () => <h1>Hello world!</h1>;

const Bar = (): JSX.Element => (
    <Foo>
        // Oops! We can add children and they will be ignored.
        <p>I can add this element but it doesn't do anything!</p>
    </Foo>
);

This can cause confusion when your component is not meant to take children! Also, if you are looking for more reasons why you should avoid React.FC, I recommend checking out this explanation by Retsam on Github for create-react-app. This PR resulted in the removal of React.FC from the Typescript template for CRA.

So now that I convinced you to think twice, what can you use instead of React.FC?

Use React.VoidFunctionComponent For Childless Components

The type was created in response to the issue that React.FC implicitly accepts children. When you use it with the example from earlier, you will see that there will be a type error indicating that Foo does not accept children!


// An example of React.VoidFunctionComponent
const Foo: React.VoidFunctionComponent = () => <h1>Hello world!</h1>;

const Bar = (): JSX.Element => (
    // There is a type error because children are not allowed!
    <Foo>
        <p>I can no longer add extra elements!</p>
    </Foo>
    
);

There’s one more thing to note. React.VoidFunctionComponent will likely be temporary. From the sounds of things, it will eventually be deprecated in favor of the naming React.FunctionComponent once React 18 is released.