35

In React, it seems that I can declare a functional component or just a function returns a JSX element. What confusing me is I don't know the key difference between these two approaches. Is there anything only one approach can do while another can not?

import React from "react";

type ItemProps = {
    id: number
    name: string
}

const Item: React.FC<ItemProps> = ({ id, name }) =>
    (
        <section>
            my id is {id}
            my name is {name}
        </section>
    )

const item = ({ id, name }: ItemProps) =>
    (
        <section>
            my id is {id}
            my name is {name}
        </section>
    )

export const Container = () =>
    (
        <section>
            {item({ id: 1, name: "item-1" })}
            <Item id={1} name={"item-1"} />
        </section>
    )

4 Answers 4

31

Summarising the differences:

React.FC:

  • has an implicit children prop, which means even if your component does not allow children, typescript would not complain if you are using React.FC and the parent passes a children. This does not impact anything at the runtime, but it is better to be more explicit about the children prop. This might be going away in the next version of React.FC, even now you can use React.VFC
  • does not work well with defaultProps
  • does not allow generics
  • can't be used to annotate a function declaration, only function expressions
  • makes "component as a namespace" pattern difficult to type

JSX.element + props interface

  • does not have an implicit children prop, so you need to declare it explicitly, which is good, and some people prefer implicit return type anyway. This does not have default support for other/static properties like propTypes, displayName etc, so they would need to be added explicitly if required.
  • does not care about default props, this is just regular function typing for arguments and return types
  • can be used with generics
  • can be used to annotate a function declaration as well as expressions

Resources

1
  • 4
    as of today the FC type does not have implicit children props because in v18 of react types the props are no longer defined as propsWithChildren.
    – HenriDev
    Commented Jul 22, 2022 at 7:38
7

React.FC offers Type checking support

You can also write components with React.FunctionComponent (or the shorthand React.FC - they are the same):

const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

Some differences from the "normal function" version:

  • React.FunctionComponent is explicit about the return type, while the normal function version is implicit (or else needs additional annotation).
  • It provides typechecking and autocomplete for static properties like displayName, propTypes, and defaultProps.
    • Note that there are some known issues using defaultProps with
      React.FunctionComponent. See this issue for details. We maintain a
      separate defaultProps section you can also look up.
  • It provides an implicit definition of children

Checkout docs for more information

https://github.com/typescript-cheatsheets/react/blob/main/README.md#section-2-getting-started

4

In React, the return of a function is JSX.Element. Even the return of the declaration in React.FC must be JSX.Element

If you have implicit return:

const Component: React.FC = () => {}

If you have explicit return

const Component = (): JSX.Element => {}
1
  • 2
    you can tell it's still early for me, you made me google chipden :facepalm:
    – Laszlo
    Commented Jan 26, 2022 at 9:59
-3

difference between these two approaches are documented here.

provides type checking and auto complete,

2
  • 3
    This is almost the answer I'm looking for. Unfortunately, the link seems to have changed so that section you referenced isn't so helpful. Furthermore, your answer doesn't specify which option provides type checking and auto complete. This leaves me as confused as I was at the start. Commented Aug 31, 2020 at 18:57
  • 2
    Dinesh, you should probably inline some more of the important bits from the link into this answer
    – KyleMit
    Commented Apr 6, 2021 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.