简体   繁体   English

Typescript,如何判断一个变量是哪个React函数组件?

[英]In Typescript, how can I tell which React functional component a variable is?

I have a CustomIcon component that I use sometimes for my icons, and other times I use MUI's icons.我有一个CustomIcon组件,有时用于我的图标,有时我使用 MUI 的图标。 I have a type with a variable defined as:我有一个变量定义为的类型:

type ParentComponentProps = {
  icon: React.ReactElement<SvgIconProps> | typeof CustomIcon;
};

This way, I can call ParentComponent either this way:这样,我可以这样调用ParentComponent

<ParentComponent icon={<HomeIcon />}/>

or要么

<ParentComponent icon={<CustomIcon {...args}/>}/>

I want a way to determine from the value of icon if it's using the MUI icon or my CustomIcon .我想要一种方法来确定icon是使用 MUI 图标还是我的CustomIcon的值。 Within ParentComponent , I want to add arguments to the icon that gets passed in so that the consumers won't have to (eg I want to add className classes in addition to what the consumer might specify).ParentComponent中,我想将 arguments 添加到传入的icon中,这样消费者就不必这样做(例如,除了消费者可能指定的内容之外,我还想添加className类)。

I've tried various ways to approach this, using typeof , instanceof , and ReturnType but they're all generally limited due to needing a value for the comparison rather than a type.我尝试了各种方法来解决这个问题,使用typeofinstanceofReturnType但它们通常都受到限制,因为需要比较值而不是类型。

Is there a way to solve this using a condition, or does it need to be solved another way?有没有办法使用条件来解决这个问题,还是需要另一种方式来解决?

the type of created react component (in the format of <Icon /> ) is always be JSX.Element , if you need to some type checks, you should pass the component itself into the props创建的 React 组件的类型(格式为<Icon /> )总是JSX.Element ,如果你需要一些类型检查,你应该将组件本身传递给 props

so the component props will be like belows, note that the name is changes to Icon because if you do <icon /> inside, it will be consider you are try to use a native element call icon :所以组件道具将如下所示,请注意名称更改为Icon因为如果你在里面做<icon /> ,它会认为你正在尝试使用原生元素调用icon

type ParentComponentProps = {
  Icon: React.ComponentType<SvgIconProps> | typeof CustomIcon;
};

but usually I will let the props of CustomIcon (assume it is called CustomIconProps ) compatible with SvgIconProps , and the types will be:但通常我会让CustomIcon的道具(假设它被称为CustomIconProps )与SvgIconProps兼容,并且类型将是:

type CustomIconProps = SvgIconProps & {
// ...
};

type ParentComponentProps = {
  Icon: React.ComponentType<SvgIconProps>;
};

which will be more clear.这会更清楚。

and the usage:和用法:

<ParentComponent Icon={HomeIcon}/>
<ParentComponent Icon={CustomIcon}/>

if you need to pass args to CustomIcon :如果您需要将args传递给CustomIcon

<ParentComponent Icon={(props: CustomIconProps) => <CustomIcon {...props} {...args}/>}/>

I want a way to determine from the value of icon我想要一种方法来确定图标的值

Where do you want to use that?你想在哪里使用它?

If you need it to determine another type, for example to type an style prop, you can do something like this:如果您需要它来确定另一种类型,例如键入style道具,您可以这样做:

      type SvgIcon = React.ReactElement<SvgIconProps>

      type ParentComponentProps<Icon extends  SvgIcon | typeof CustomIcon> = {
               icon: Icon;
               style: Icon extends SvgIcon ? Type1 : Type2
        
       };

Even when you do:即使你这样做:

<ParentComponent
  icon={<CustomIcon {...args}/>}
/>

...you are actually passing a ReactElement to the icon prop. ...您实际上是将ReactElement传递给icon道具。

More generally, this is similar to the children prop, or any slot content prop.更一般地说,这类似于children道具或任何插槽内容道具。 We generally type them as ReactNode , which also takes a string , null , or an array of ReactNode .我们通常将它们键入为ReactNode ,它也接受一个string null或一个ReactNode数组。

It is indeed possible to tell from a ReactElement from which Component it was built, typically by looking into its type.name property, but you need to guard it first, as described eg in Accessing child.type.name in React Typescript确实可以从ReactElement中判断它是由哪个组件构建的,通常是通过查看其type.name属性,但您需要首先保护它,如Accessing child.type.name in React Typescript 中所述

function ParentComponent({
    icon
}: {
    icon: React.ReactElement
}) {
    if (React.isValidElement(icon) && typeof icon.type === "function") {
        icon.type.name // Okay
    }
    return <></>
}

Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何刷新 React Functional 组件? - How can I refresh React Functional component? react 功能组件如何使用在用法后面声明的 object 变量? (包括例子) - How react functional component can use object variable which declared behind the usage? (include example) 我应该如何在 React 中使用 Typescript 声明无状态功能组件? - How should I declare a Stateless Functional Component with Typescript in React? React 和 Typescript 功能组件可以是 3 个接口之一 - React and Typescript functional component can be 1 of 3 interfaces 如何告诉我的React app我想在Firestore中更新哪个组件? - How can I tell my React app which component I want to update in Firestore? 反应:如何访问 class 组件中的功能组件的道具 - React: How can I acces to props of a functional component in a class component 我怎样才能把这个 React class 组件变成一个功能组件? - How can i turn this React class component into a functional component? 我如何编写此类组件来响应功能组件。? - How can i write this class component to react functional component.? 如何在反应功能组件中为按钮变量切换 className? - How do I toggle className for button variable in react functional component? 如何判断 React 功能组件是否已在代码中呈现? - How to tell if a React functional component has been rendered in code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM