Typescript React.FC<Props> confusion

人走茶凉 提交于 2020-12-24 15:20:18

问题


I am learning typescript and some bits are confusing to me. One bit is below:

interface Props {
  name: string;
}

const PrintName: React.FC<Props> = (props) => {
  return (
    <div>
      <p style={{ fontWeight: props.priority ? "bold" : "normal" }}>{props.name}</p>
    </div>
  )
}


const PrintName2 = (props:Props) => {
  return (
    <div>
      <p style={{ fontWeight: props.priority ? "bold" : "normal" }}>{props.name}</p>
    </div>
  )
}

For both functional components above, I see TypeScript generates same JS code. The PrintName2 component seems more streamline to me as far as readability. I wonder whats the difference between the two definitions and is anyone is using second type of react components.


回答1:


Thanks all for answers. They are correct but I was looking for a more detailed version. I did some more research and found this on react-typescipt cheatsheet on github: https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#reacttypescript-cheatsheets

Function Components
These can be written as normal functions that take a props argument and return a JSX element.

type AppProps = { message: string }; /* could also use interface */
const App = ({ message }: AppProps) => <div>{message}</div>;

What about React.FC/React.FunctionComponent? You can also write components with React.FunctionComponent (or the shorthand React.FC):

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

Some differences from the "normal function" version:

It provides typechecking and autocomplete for static properties like displayName, propTypes, and defaultProps - However, there are currently known issues using defaultProps with React.FunctionComponent. See this issue for details - scroll down to our defaultProps section for typing recommendations there.

It provides an implicit definition of children (see below) - however there are some issues with the implicit children type (e.g. DefinitelyTyped#33006), and it might considered better style to be explicit about components that consume children, anyway.

const Title: React.FunctionComponent<{ title: string }> = ({
  children,
  title
}) => <div title={title}>{children}</div>;

In the future, it may automatically mark props as readonly, though that's a moot point if the props object is destructured in the parameter list.

React.FunctionComponent is explicit about the return type, while the normal function version is implicit (or else needs additional annotation).

In most cases it makes very little difference which syntax is used, but the React.FC syntax is slightly more verbose without providing clear advantage, so precedence was given to the "normal function" syntax.




回答2:


React.FC is not the preferable way to type a React component, there's a link.

I personally use this type:

const Component1 = ({ prop1, prop2 }): JSX.Element => { /*...*/ }

Short list of React.FC cons:

  1. Provides an implicit definition of children. Even if your component doesn't needs to have a childrens, that might cause an error.
  2. Doesn't support generics.
  3. Doesn't work correctly with defaultProps.



回答3:


The first version will add a few types for you - they come from React.FC

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

This is useful for a few reasons but an obvious one is if your component has children. Then you don't need to manually add a children prop




回答4:


Since you are using React and TypeScript, you should always use the first pattern, as it will ensure that your component is more strictly typed since it implies that the PrintName will be of type React Functional Component, and it takes in props of type Props.

const PrintName: React.FC<Props>

You may read the full interface definition for Functional Components on the React TypeScript typings repository.

The second example you have provided does not provide any form of typings, except that it is a function that takes a set of parameters of type Props, and that it can return anything in general.

Therefore, writing

const PrintName2 = (props:Props)

is akin to

const PrintName2: JSX.Element = (props:Props) 

as TypeScript is definitely unable to automatically infer that it is a Functional Component.



来源:https://stackoverflow.com/questions/59988667/typescript-react-fcprops-confusion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!