反应 FC < 道具 > 混乱

我正在学习 TypeScript,有些地方让我感到困惑,其中一个地方如下:

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>
)
}

对于上面的两个函数组件,我看到 TypeScript 生成了相同的 JS 代码。就可读性而言,PrintName2组件似乎更加流线型。我想知道这两个定义之间的区别是什么,如果有人使用第二种类型的反应组件?

225384 次浏览

最佳解决方案:

第二种方法 + 返回类型

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

这样你就可以完全控制道具,并且更加明确(没有隐藏的魔法)。

链接到 GitHub PR 以删除 React.FC

肯特 · C · 多兹对此有些想法

次优解决方案:

第一个版本(React.FC)将为您添加一些类型——它们来自 反应类型

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

这种方法有几个有用的原因,但是一个明显的原因是,如果您的组件有子组件,那么您就不需要手动添加 children道具。这并不好,因为缺省道具存在问题,而且许多组件没有子组件。

因为您使用的是 React 和 TypeScript,所以应该始终使用第一种模式,因为它将确保组件的类型更加严格,因为它意味着 PrintName将是 React Functional Component 类型,并且它采用 Props类型的道具。

const PrintName: React.FC<Props>

您可以阅读 React TypeScript 类型 储存库上的 Functional Component 的完整接口定义。

您提供的第二个示例没有提供任何形式的类型,除了它是一个接受 Props类型的一组参数的函数,并且它通常可以返回任何内容。

因此,写作

const PrintName2 = (props:Props)

类似于

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

因为 TypeScript 无法自动推断它是一个 Functional Component。

谢谢你的回答。他们是正确的,但我正在寻找一个更详细的版本。我又做了些调查,在 GitHub 的 React + TypeScript 备忘录上找到了这个。

功能组件
这些函数可以写成普通函数,它们接受一个 props 参数并返回一个 JSX 元素。

type AppProps = { message: string }; /* could also use interface */


const App = ({ message }: AppProps) => <div>{message}</div>;

React.FC/React.FunctionComponent呢? 您还可以使用 React.FunctionComponent(或简写 React.FC)编写组件:

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

与“正常函数”版本的一些不同之处:

它为诸如 displayNamepropTypesdefaultProps这样的静态属性提供了类型检查和自动完成功能——然而,目前在使用 defaultPropsReact.FunctionComponent时存在已知的问题。详细信息请参阅 问题-向下滚动到我们的 defaultProps部分,在那里输入建议。

它提供了子元素的隐式定义(见下文)——但是隐式子元素类型有一些问题(例如 Definition itelyType # 33006) ,无论如何,显式地定义使用子元素的组件可能被认为是更好的风格。

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

将来,它可能会自动将道具标记为只读,但是如果道具对象在参数列表中被解构,那就没有意义了。

React.FunctionComponent是显式的返回类型,而普通函数版本是隐式的(或者需要额外的注释)。

在大多数情况下,使用哪种语法几乎没有什么区别, 但是 React.FC语法稍微有点冗长,没有提供 明显的优势,所以优先考虑的是“正态函数” 语法。

React.FC不是输入 React 组件的最佳方式,这里是 链接

我个人使用这种类型:

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

React.FC缺点简单列表:

  1. 提供子级的隐式定义,即使您的组件不需要子级。这可能会导致错误。
  2. 不支持泛型。
  3. defaultProps无法正常工作。