简体   繁体   English

为什么 React.FunctionComponenent 优于传统的函数定义?

[英]Why is React.FunctionComponenent preferred over conventional function definitions?

I've always defined React components (with typescript) as:我一直将 React 组件(使用打字稿)定义为:

function MyComponent(props: PropsType): React.ReactElement | null {
    //...
}

Online I see a lot of examples like:在网上我看到很多这样的例子:

const MyComponent: React.FC = (props: PropsType) => {
    //...
}

I understand they are pretty much the same, but what is the preferred convention in the Typescript community?我知道它们几乎相同,但是 Typescript 社区中的首选约定是什么?

Quoting React-Typescript Cheatsheet on Github在 Github 上引用React-Typescript Cheatsheet

You can also write components with React.FunctionComponent (or the shorthand React.FC ):您还可以使用React.FunctionComponent (或简写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 .它为displayNamepropTypesdefaultProps等静态属性提供类型检查和自动完成 -但是,当前存在将defaultPropsReact.FunctionComponent使用的已知问题。 See this issue for details有关详细信息,请参阅此问题
  • It provides an implicit definition of children (see below) - however there are some issues with the implicit children type (egDefinitelyTyped#33006 ), and it might considered better style to be explicit about components that consume children , anyway.它提供了一个隐含的定义children (见下文) -但也有一些问题,隐含children类型(例如DefinitelyTyped#33006 ),它可能认为是更好的风格是明确约消耗部件children ,无论如何。
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 constructor.将来,它可能会自动将 props 标记为readonly ,尽管如果 props 对象在构造函数中被解构,这是一个有争议的问题。

  • React.FunctionComponent is explicit about the return type, while the normal function version is implicit (or else needs additional annotation). React.FunctionComponent对返回类型是显式的,而普通函数版本是隐式的(否则需要额外的注解)。

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.在大多数情况下,使用哪种语法几乎没有区别,但React.FC语法稍微冗长,没有提供明显的优势,因此优先考虑“普通函数”语法。

In addition to Boy With Silver Wings answer - The core advantage is that the arrow function expression component ( const Foo () => <div>Hello</div> ) itself could be typed:除了Boy With Silver Wings 答案- 核心优势是箭头函数表达式组件( const Foo () => <div>Hello</div> )本身可以键入:

const Foo: YourOwnTypeAliasOrInterface = () => <div>Hello</div>

React.FC implements as being said a couple of types for you (children, or possible return types). React.FC为您实现了几种类型(子项或可能的返回类型)。 You can't do that with your named function component:你不能用你的命名函数组件来做到这一点:

function Foo<YourOwnTypeAliasOrInterface>() { // this does not work!! (Only with generics)
  return <div>Hello</div>
}

TL;TR with React.FunctionalComponent you simply have to type less, because types such as return type and children is already defined. TL;TR 使用React.FunctionalComponent你只需要少输入,因为返回类型和 children 等类型已经定义。

type FooProps = {
  title: string;
} & React.FC // <-- intersection type, so it has FooProps and React.FC typings

const Foo: FooProps = ({ children, title }) => { ... }

Create React App recently dropped FC / FunctionComponent type usage from the TypeScript template. Create React App 最近从 TypeScript 模板中删除了FC / FunctionComponent类型的使用。


Downsides of FC : FC缺点:

  • implicit optional children - better define your props API explicitely隐式可选children - 更好地明确定义您的道具 API

  • no generic component creation possible无法创建通用组件

  • no need to have explicit ReactElement | null无需显式ReactElement | null ReactElement | null return type, which in addition is not accurate ; ReactElement | null返回类型,另外也不准确 it can be 1) better inferred automatically by TS or 2) set explicitely它可以是 1) 更好地由 TS 自动推断或 2) 明确设置

  • FC is just a wrapper for statics like contextTypes , propTypes , etc. which aren't needed in most cases FC只是像contextTypespropTypes等静态propTypes的包装器,在大多数情况下是不需要的

  • doesn't work well with defaultProps (Note: JS default args should be preferred anyway)不适用于defaultProps (注意:无论如何都应该首选JS 默认参数)

  • no need to remember "magic" types - just use functions for components无需记住“魔法”类型 - 只需为组件使用函数

  • doesn't make your code (much) leaner不会让你的代码(很多)更精简


So in summary, I would rather state the opposite: plain (arrow) functions > React.FC .所以总而言之,我宁愿反其道而行之:普通(箭头)函数> React.FC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM