React.FC 和函数之间的 React TypeScript 区别<T> ()



箭头函数和函数符号之间有区别吗?

以下两个组件的工作原理似乎相同。

一个被实现为React.FC<T>,另一个被实施为Function()

这只是一种不同的符号,还是有其他原因?

AuthRoute.tsx作为React.FC:

import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { useAuthContext } from './AuthContext';
import RoutesUrls from './routesUrls';
export interface IAuthRouteProps {
component: React.ComponentType;
path: string;
exact?: boolean;
}
const AuthRoute: React.FC<IAuthRouteProps> = (props) => {
const { authorized } = useAuthContext();
if (authorized) {
return (
<Route
component={props.component}
exact={props.exact}
path={props.path}
/>
);
} else {
return <Redirect to={RoutesUrls.LOGIN} />;
}
};
export default AuthRoute;

AuthRoute.tsx作为Function()

import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { useAuthContext } from './AuthContext';
import RoutesUrls from './routesUrls';
export interface IAuthRouteProps {
component: React.ComponentType;
path: string;
exact?: boolean;
}
export default function AuthRoute(props: IAuthRouteProps) {
const { authorized } = useAuthContext();
if (authorized) {
return (
<Route
component={props.component}
exact={props.exact}
path={props.path}
/>
);
} else {
return <Redirect to={RoutesUrls.LOGIN} />;
}
}

FC是功能组件(顾名思义(

检查FC 的实施情况

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

它只有可选字段propTypes, contextTypes,这些字段是键入的,在编写代码时会有所帮助

就我个人而言,当我不需要反应道具验证、上下文或默认道具声明时,我更喜欢功能组件,而且写的时间更短

type Prop = { name: string }
const Test0: FC<Prop> = (prop: Prop) => null
Test0.defaultProps = {
name: 'Sam' // typed, with vs-code autocomplete
}
function Test1(prop: Prop) { return null }
Test1.defaultProps = {
name: 'Sam' // untyped, no autocomplete
}

就是这样。

简短回答:

如果您想更深入地了解组件类型以提高TS编译时间(而不是代码性能(,请使用React.FC

如果您喜欢function表示法,请随意使用。

无论如何,编译后的代码都是一样的。

长答案

如果要缩小组件返回类型,则应使用React.FC

让我们从一个简单的例子开始,部分取自这里:

import React from 'react'
type Props = {
label: string
}
function A() {
return <div>Child One</div>;
}
const B: React.FC<Props> = ({ label }) => {
return <div>{label}</div>;
};
/**
* Assume, You want to allow only children with particular props
* In our case - props of children should match Props type
*/
function Parent({
children
}: {
children: React.ReactElement<{ label: string }>[];
}) {
return (
<div>{
children.map((child) => (
<div key={child.props.label}>{child}</div>
))
}</div>
)
}
function App() {
/**
* There is no TS error and it is almost expected ))
*/
return <Parent children={[<A />, <B label={'hello'} />]} />;
}

因此,我们需要帮助TS适当地缩小应用程序子类型。让我们为孩子们使用本机语法,而不是JSX

// Please replace App in prev example with App2
function App2() {
return React.createElement(Parent, {
children: [
/**
* Here should be an error, because all
* children of Parent should have Props
* 
* Why there is no error?
* 
* Because TS can't figure out proper type from A component annotation
*/
React.createElement(A), 
React.createElement(B, { label: 'd' })
]
});
}

为了让它发挥作用,我们只需要更换:

function A() {
return <div>Child One</div>;
}

带有

const A: React.FC = () => {
return <div></div>;
};

瞧,我们有一个错误Property 'label' is missing in type '{}' but required in type '{ label: string; }'

完整工作示例:

import React from 'react'
type Props = {
label: string
}
const A: React.FC = () => {
return <div></div>;
};

const B: React.FC<Props> = ({ label }) => {
return <div>{label}</div>;
};
/**
* Assume, You want to allow only children with particular props
* In our case - props of children should match Props type
*/
function Parent({
children
}: {
children: React.ReactElement<{ label: string }>[];
}) {
return (
<div>{
children.map((child) => (
<div key={child.props.label}>{child}</div>
))
}</div>
)
}
function App2() {
return React.createElement(Parent, {
children: [
/**
* Here should be an error, because all
* children of Parent should have Props
* 
* Why there is no error?
* 
* Because TS can't figure out proper type from A component annotation
*/
React.createElement(A), 
React.createElement(B, { label: 'd' })
]
});
}

我明白了,我没有说服你。好的,我理解。让我们看看下一个例子。假设,你想从一个组件返回某种特定类型的其他组件

import React from 'react'
function Two(){
return <div></div>
}
type Props = {
label: string;
}
type CustomReturn = React.ReactElement<Props>;

const MainButton: React.FC<Props> = (prop: Props): CustomReturn => 
React.createElement(Two); // no error, but should be

尽管我已经明确定义了返回类型,但根本没有错误。让我们使用React.FC:

import React from 'react'
const Two: React.FC = () => <div></div>
type Props = {
label: string;
}
type CustomReturn = React.ReactElement<Props>;

const MainButton: React.FC<Props> = (prop: Props): CustomReturn => 
React.createElement(Two); // Error, as it should be

使用React.FC,TS能够推断类型。

相关内容

  • 没有找到相关文章