如何在 TypeScript v2.x 中从自定义 React 组件公开“通用”事件

Posted

技术标签:

【中文标题】如何在 TypeScript v2.x 中从自定义 React 组件公开“通用”事件【英文标题】:How to expose a 'generic' event from a custom React component in TypeScript v2.x 【发布时间】:2017-08-28 13:35:44 【问题描述】:

当我们还在使用 Typescript 1.8.x 结合当时 React 的 (Definitely Typed) 类型描述文件时,我们使用 'Event' 类型在 React 组件属性中声明一个 'generic' 事件。然后我们可以将该属性的值(存在和事件处理函数)附加到例如 htmlInputElement 的“onChange”属性。

interface IIcoonProps 
    onClick?: Event;


interface IIcoonDetails 
    cssClass: string;
    standaardTooltip: string;


class Icoon extends React.Component<IIcoonProps, > 



public render(): JSX.Element 

    return (<span   className=klassenamen
                    title=nieuweTooltip
                    onClick=this.props.onClick />);
    

我们最近更新到 TypeScript 2.2.2,还更新了我们正在使用的类型定义。现在我们不能再使用通用的 'Event' 类型了,因为它会导致像“Type 'Event' is not assignable to type 'EventHandler>'”这样的异常。

当然,当我将自定义组件的属性界面中的属性类型改为'React.MouseEvent'时,问题就解决了。但是.....我不想让这个组件的父组件知道底层类型(在这个例子中是HtmlInputElement),因为它是我自己组件的属性中提到的一个事件。我只需要将事件传递给父组件,因为我希望父组件能够使用事件的“PreventDefault”等方法。我在 IComponentProps 接口中使用不同的属性和方法来发布例如更改的文本输入值。

下面的代码可以运行,但并不理想。

interface IIcoonProps 
    onClick?: React.EventHandler<React.MouseEvent<HTMLSpanElement>>;


interface IIcoonDetails 
    cssClass: string;
    standaardTooltip: string;


class Icoon extends React.Component<IIcoonProps, > 

public render(): JSX.Element 

    return (<span   className=klassenamen
                    title=nieuweTooltip
                    onClick=this.props.onClick />);
    

有谁知道如何在使用 TypeScript 和 React 时使用泛型类型来处理事件,就像我们之前使用 'Event' 类型时所做的那样,而不使用泛型(如 MouseEvent)。

更新:添加代码示例

【问题讨论】:

您能否添加一个显示问题的代码示例? @NitzanTomer 我添加了一个代码示例。我不希望父组件知道“Icoon”组件的底层 Html 是“HtmlSpanElement”。当我将来需要更改它时,我可能需要更改所有使用“Icoon”组件的组件。 【参考方案1】:

您的代码对我来说似乎很好,但如果您不想具体说明目标元素的类型,那么您可以使用HTMLElement:

interface IIcoonProps 
    onClick?: React.EventHandler<React.MouseEvent<HTMLElement>>;

这将适用于未来可能发生的变化(假设从 HTMLSpanElementHTMLDivElement)。

另外,您可以改用此签名:

interface IIcoonProps 
    onClick?: (event: React.MouseEvent<HTMLElement>) => void;


编辑

如果您想要使用非通用接口,那么您可以创建自己的然后使用它:

type MouseEvent = React.MouseEvent<HTMLElement>;

interface IIcoonProps 
    onClick?: (event: MouseEvent) => void;

【讨论】:

不是我所希望的答案,但这是我所期望的。感谢您提出使用 HtmlElement 代替专用标签的建议。这将提高代码的可维护性。 你希望得到什么? 我希望有一个不使用泛型并公开诸如 preventDefault 之类的方法的接口。我可以将此接口作为可选参数添加到回调函数中。 检查我修改后的答案 这并没有真正改变解决方案,但看起来更简单。 MouseEvent 只是充当别名。我对你最初的回答很好!

以上是关于如何在 TypeScript v2.x 中从自定义 React 组件公开“通用”事件的主要内容,如果未能解决你的问题,请参考以下文章

如何从自定义实现中引用“正常”弹簧数据存储库?

如何从自定义 UITableViewCell 调用操作以重新加载 tableView

swift:从自定义应用程序加载时,iCloud 文档似乎被禁用

将 React 组件从自定义组件库导入 HTML

如何在 TypeScript 中从日期中减去天数

如何在 Angular 5 中从 Typescript 调用 JavaScript 函数?