reactjs TypeScript中的React组件类型

v09wglhw  于 2023-01-25  发布在  React
关注(0)|答案(7)|浏览(219)

在TypeScript中描述react组件类型的正确方法是什么?假设我们有一个返回react组件的函数。该函数:

const getTabContent: () => ReactElement = () => {
  switch (tab) {
    case 1:
      return <Images images={images} onSelect={onSelect}/>;
    default:
      return <Search onSelect={onSelect}/>;
  }
};

这里我把返回的类型描述为ReactElement,但是我想知道它是否正确,或者我应该把它描述为ReactComponentElement,或者甚至完全不同?另外,这两个类型都是泛型,如果其中一个是正确的,如何完整地描述它们?
UPD ReactElement似乎适合这里,因为,例如,FC(FunctionComponent)返回它

xzabzqsa

xzabzqsa1#

功能组件的正确类型是React.FunctionComponentReact.FC,后者是功能组件的快捷别名

import React, { FC } from 'react';

const getTabContent: FC = () => {
  switch (tab) {
    case 1:
      return <Images images={images} onSelect={onSelect}/>;
    default:
      return <Search onSelect={onSelect}/>;
  }
};

FC类型只是将children属性添加到功能组件的props参数中,以便您可以访问它:

const SomeComponent: FC = ({ children }) => (
  <div className="hello">{children}</div>
);

FC是一个泛型类型,因此您可以向组件"添加" prop :

interface SomeComponentProps {
  foo: string;
}

const SomeComponent: FC<SomeComponentProps> = ({ children, foo }) => (
  <div className={`Hello ${foo}`}>{children}</div>
);
    • 编辑:React 18更新**

从React18开始,FC就不再隐式添加children属性,而是提供了一种显式的方法来使用PropsWithChildren generix类型添加属性
示例:

type SomeComponentProps = { a: string };

const SomeComponent: FC<SomeComponentProps> = ({ a }) => <div>{a}</div>;

// This will fail when using the following expression
<SomeComponent>Hey I'm a child</SomeComponent>

儿童使用:

type ComponentWithChildrenProps = PropsWithChildren<{ a: string }>;

const ComponentWithChildrenProps: FC<ComponentWithChildrenProps> = ({
  a,
  children
}) => <div>{a} and {children}</div>

这允许有一个children prop 有点严格。

type StrictCompProps = { children: string };

const StrictComp: FC<StrictCompProps> = ({ children }) => <div>{children}</div>;

// This will fail
<StrictComp><span>hey</span></StrictComp>
jm2pwxwz

jm2pwxwz2#

如果你想把函数组件和类组件一起使用,那么就使用React.ComponentType

dpiehjr4

dpiehjr43#

考虑React中的内置定义:

type PropsWithChildren<P> = P & {
    children?: React.ReactNode;
}

我使用的是React.ReactNode,它被定义为

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
sq1bmfud

sq1bmfud4#

TypeScript提供了强大的类型推理。在大多数情况下都可以使用它。只有顶级组件需要细粒度接口。
例如,这里的结果类型将被计算为JSX.Element

const getTabContent = ({ tab, onSelect }: { tab: number, onSelect: (ev: React.SyntheticEvent) => void }) => {
  switch (tab) {
    case 1:
      return <Image src="123"/>;
    default:
      return <Search onSelect={onSelect}/>;
  }
};
0ejtzxu1

0ejtzxu15#

最好的选择是ComponentType。如果你对函数组件要求严格,你可以使用FC。在某些情况下,你可能需要类组件类型和函数组件类型的支持。(例如,定义一个prop类型,prop需要一个组件,函数组件或类组件)。
推荐的方法是在类型定义中使用ComponentType(即ProopTypes),当您要定义返回类型等时使用FC
仅供参考,以下是 typescript 中ComponentTypeFC的定义

type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
type FC<P = {}> = FunctionComponent<P>;
hpxqektj

hpxqektj6#

使用类型定义组件并在其他位置使用它的简单示例:
第1步:像这样定义组件:

import React from "react";

const HomePage: React.FC = () => {
  return (
    <div>
      <h3>Home Page</h3>
    </div>
  );
};

export default HomePage;

步骤2:定义接口以描述功能组件类型:

export interface IRouteDto {
    id: number,
    path: string,
    faTitle: string
    element: React.FC,
}

步骤3:轻松使用界面:

export const routes: IRouteDto[] = [
    {id: 1, path:"/", faTitle: "خانه", element:HomePage}
    {id: 2, path:"/about", faTitle: "درباره ما", element:AboutPage},
    {id: 3, path:"/contact-us", faTitle: "تماس با ما", element:ContactUsPage},
]
5f0d552i

5f0d552i7#

React.ReactNode是定义React元素类型的正确方法。

相关问题