用TypeScript强类型化这个强大而灵活道具的不同方法

196 阅读2分钟

React children道具允许组件被组合在一起,是构建可重用组件的一个关键概念。从视觉上看,我们可以把它看作是组件中的一个洞,消费者在那里控制渲染的内容。这篇文章介绍了用TypeScript强类型化这个强大而灵活的道具的不同方法:

React Children with TypeScript 使用FC 类型

有一个标准的React类型,FC ,我们可以在箭头函数组件上使用。FCFunction Component的缩写,它与一个叫做FunctionComponent 的类型相类似。

这里有一个例子:

type Props = {
  title: string,
};
const Page: React.FC<Props> = ({
  title,
  children,
}) => (
  <div>
    <h1>{title}</h1>
    {children}
  </div>
);

FC 是一个通用类型,它接收所有组件道具的具体类型。在上面的例子中,我们传入了一个 类型的别名,其中包含一个 的道具。另外,也可以用一个接口来定义 。Props title Props

注意,children 并没有定义在Props 。相反,它已经被定义在FC 类型中。如果你知道这个事实,这很好,但如果你不知道,可能就会有点困惑了。

明确定义children 道具类型

如果我们明确地定义children ,我们有几个不同的选项来定义其类型。

让我们一个一个来看看 ...

使用JSX.Element

让我们先试试JSX.Element

type Props = {
  title: string,
  children: JSX.Element,};
const Page = ({ title, children }: Props) => (
  <div>
    <h1>{title}</h1>
    {children}
  </div>
);

children 是目前必须的。如果我们想让这个组件的消费者可以选择,我们在类型注解前加一个问号( )。?

type Props = {
  title: string;
  children?: JSX.Element;};

JSX.Element 如果孩子被要求是一个单一的React元素,那就很好。然而,它不允许有多个孩子。所以,我们可以做如下调整:

type Props = {
  title: string;
  children?: JSX.Element | JSX.Element[];};

使用ReactChild

JSX.Element 的一个缺点是它不允许有字符串。所以,我们可以在联合类型中加入字符串:

type Props = {
  title: string;
  children:    | JSX.Element    | JSX.Element[]    | string    | string[];};

...但是数字呢?

......这就失控了!

幸运的是,有一个标准类型叫ReactChild ,它包括React元素、字符串和数字。因此,我们可以扩大children 的类型,如下所示:

type Props = {
  title: string;
  children?:    | React.ReactChild    | React.ReactChild[];};

使用ReactNode

React.ReactChild | React.ReactChild[] 提供了我们需要的广泛的值,但有点啰嗦。 是一个更简洁的选择。ReactNode

type Props = {
  title: string;
  children?: React.ReactNode;};

ReactNode 允许多个元素、字符串、数字、片段、门户......。

非常完美!

FC 通用类型在引擎盖下也使用ReactNode

类组件

如果我们使用的是类组件呢?让我们来探讨这个问题:

type Props = {
  title: string,
};
export class Page extends React.Component<Props> {
  render() {
    return (
      <div>
        <h1>{this.props.title}</h1>
        {this.props.children}
      </div>
    );
  }
}

FCComponent 类型自动包括children 道具。

如果我们将鼠标悬停在children 道具上,我们会发现它被赋予的类型。

Class children

所以,类组件中的children 道具的类型也是ReactNode

结束语

如果我们使用类型为FC 的函数组件,那么children 道具就已经被输入了。如果我们明确地对children 道具进行类型化,一般来说,ReactNode 是最好的选择。