我正在学习打字稿,有些地方让我感到困惑。以下是一位:
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
组件对我来说似乎更加精简。我想知道这两个定义之间的区别是什么,有人在使用第二种类型的react组件。
答案 0 :(得分:18)
谢谢大家的回答。他们是正确的,但我正在寻找更详细的版本。我进行了更多研究,并在github上的react-typescipt速查表上找到了这一点:https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#reacttypescript-cheatsheets
功能组件
这些可以写为带有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>
);
与“正常功能”版本有所不同:
它为displayName,propTypes和defaultProps之类的静态属性提供类型检查和自动完成功能-但是,当前存在将defaultProps与React.FunctionComponent一起使用的已知问题。有关详细信息,请参见此问题-向下滚动到我们的defaultProps部分,以在其中键入建议。
它提供了子代的隐式定义(请参阅下文)-但是隐式子代类型存在一些问题(例如DefinitelyTyped#33006),并且无论如何,它可能认为更好的样式对于使用儿童的组件是明确的。 / p>
const Title: React.FunctionComponent<{ title: string }> = ({
children,
title
}) => <div title={title}>{children}</div>;
将来,它可能会自动将props标记为只读,但是如果props对象在参数列表中被破坏,那将是一个有争议的问题。
React.FunctionComponent关于返回类型是显式的,而普通函数版本是隐式的(否则需要附加注释)。
在大多数情况下,使用哪种语法几乎没有什么区别, 但是React.FC语法在没有提供的情况下更加冗长 明显的优势,因此优先考虑“正常功能” 语法。
答案 1 :(得分:14)
React.FC
不是键入React组件的首选方法,有link。
我个人使用这种类型:
const Component1 = ({ prop1, prop2 }): JSX.Element => { /*...*/ }
React.FC
缺点的简短列表:
答案 2 :(得分:3)
第一个版本将为您添加一些类型-它们来自React.FC
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
这出于几个原因很有用,但很明显的一个原因是您的组件是否有子级。然后,您无需手动添加儿童道具
答案 3 :(得分:2)
由于您使用的是React和TypeScript,因此您应始终使用第一种模式,因为这将确保您的组件的输入更为严格,因为这意味着PrintName
的类型将是React Functional Component,并且接受Props
类型的道具。
const PrintName: React.FC<Props>
您可以在React TypeScript类型为repository的情况下阅读功能组件的完整接口定义。
您提供的第二个示例不提供任何形式的键入,只是它是一个带有一组Props
类型的参数的函数,并且它可以返回任何常规值。
因此,写作
const PrintName2 = (props:Props)
类似于
const PrintName2: JSX.Element = (props:Props)
因为TypeScript绝对无法自动推断出它是一个功能组件。