Skip to main content

fc-not-fc

Using React with TypeScript, you might come across two common ways of defining functional components and their props: using React.FC (or React.FunctionComponent) and destructuring props with a type or interface. Each method has its nuances and implications. Here's a comparison of the two approaches as of my last update in April 2023:

Using React.FC or React.FunctionComponent

  1. Type Definition:

    • React.FC or React.FunctionComponent is a generic type that makes your component type explicitly a React function component.
    • It can provide type-checking and autocomplete for static properties like propTypes, contextTypes, defaultProps, and displayName.
  2. Children Prop:

    • React.FC automatically includes the children prop, whether you use it in your component or not. This can be convenient but might lead to less control or clarity over which components expect to render children.
  3. Implicit Return Type:

    • When using React.FC, the return type of the component is implicitly set to ReactElement | null, ensuring that your component returns a valid React element.

Destructuring Props with a Type or Interface

  1. Explicit Prop Definition:

    • When you define a type or an interface for your props and destructure them in the function parameters, you explicitly state what props your component expects.
    • This approach gives you full control over your prop types, including whether or not your component expects children.
  2. No Implicit Children:

    • Unlike React.FC, this method does not automatically include the children prop. You need to explicitly define it if your component is going to use children.
  3. Return Type:

    • The return type of the component is not implicitly set, so you might need to explicitly define it if you want to enforce that the component returns a valid React element.
  4. Flexibility and Clarity:

    • This approach is often considered more flexible and clear, as it avoids the implicit behaviors of React.FC, making the components more predictable.

Example Comparison

Using React.FC:

import React from 'react';

interface Props {
title: string;
}

const MyComponent: React.FC<Props> = ({ title }) => {
return <h1>{title}</h1>;
};

Destructuring Props:

import React from 'react';

interface Props {
title: string;
}

const MyComponent = ({ title }: Props) => {
return <h1>{title}</h1>;
};

Conclusion

  • Preference: The choice between these two approaches often comes down to personal or team preference. Some developers prefer the explicitness and control of defining props separately, while others appreciate the convenience of React.FC.
  • Trends: There has been a trend in the React community towards avoiding React.FC for more explicit control, particularly over children and return types.
  • Consistency: Whichever approach you choose, maintaining consistency across your codebase is beneficial for readability and maintainability.