使用 Typescript 和 React 中的 Abort Signal 删除事件处理程序

Tyl*_*ler 6 events typescript reactjs

我正在构建一个门户,最终获取类似 xml 的文档并将其显示在浏览器中,每当我加载这些页面之一时,我都需要将 onclick 和 mouseover 处理程序附加到页面上的多个元素。

但是,用户可以在其中几个页面之间导航,并且我遇到了将多个处理程序附加到单个元素的问题。

因此,我想附加一个包含中止信号的处理程序,这样每当我更改页面时,我就可以暗示中止并立即删除所有处理程序,但我似乎无法让打字稿一起运行。

代码示例:

    export const attachElementModifiers = (
      elementObject: { [key: string]: Element },
      elementPointerClass: string,
      listener: (evt: any) => void,
      onHoveringHandler: (_evt: any, key: string) => void,
      onMouseOutHandler: (_evt: any) => void,
      controller: AbortController
    ): void => {
      for (const [key] of Object.entries(elementObject)) {
        elementObject[key].classList.add(elementPointerClass)
        elementObject[key].addEventListener('click', listener)
        elementObject[key].addEventListener('mouseover', (_evt: any) =>
          onHoveringHandler(_evt, key)
        )
        elementObject[key].addEventListener(
          'mouseleave',
          (_evt: any) => onMouseOutHandler(_evt),
          { signal: controller.signal }  // <---- ERROR HERE
        )
      }
    }
Run Code Online (Sandbox Code Playgroud)

总是出现以下错误:

No overload matches this call.
  Overload 1 of 2, '(type: keyof ElementEventMap, listener: (this: Element, ev: Event) => any, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
    Argument of type '"mouseleave"' is not assignable to parameter of type 'keyof ElementEventMap'.
  Overload 2 of 2, '(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
    Argument of type '{ signal: AbortSignal; }' is not assignable to parameter of type 'boolean | AddEventListenerOptions | undefined'.
      Object literal may only specify known properties, and 'signal' does not exist in type 'AddEventListenerOptions'.ts(2769)
Run Code Online (Sandbox Code Playgroud)

我知道 AbortSignal 存在于 lib.dom.d.ts 中,但是我不确定如何在这里正确使用它。

Fra*_*man 7

您可以通过以下方式修复此问题

elementObject[key].addEventListener(
  'mouseleave',
  (_evt: any) => onMouseOutHandler(_evt),
  { signal: controller.signal }   as AddEventListenerOptions
)
Run Code Online (Sandbox Code Playgroud)

选项对象导致了该错误,即使它具有与 AddEventListenerOptions 接口匹配的属性,仍然需要告诉它它是一个 AddEventListenerOptions。