useEffect不会删除我的事件侦听器

比耶尔先生

我有一个自定义钩子,可以设置多个按预期工作的事件侦听器。但是我注意到,事件监听器在重新渲染时不会被删除。我做错了什么(代码后半部分的事件监听器)?也就是说,我在锚标记事件中注意到了它;handleLink

export default function useCursorSelector(
  selectorRef: React.RefObject<HTMLElement>,
  onClickLink: (url: string) => void,
  onSelect: (text: string) => void
) {
  const classes = useStyles();

  const handleSelection = React.useCallback(
    (event: MouseEvent) => {
      const selection: Selection | null = window.getSelection();
      if (selection) {
        const text = fullStringSelection(selection);
        selection.removeAllRanges();
        onSelect(text);
      }
      event.stopPropagation();
    },
    [onSelect]
  );

  const handleLink = React.useCallback(
    (a: HTMLAnchorElement) => (e: MouseEvent) => {
      e.preventDefault();
      onClickLink(a.href);
    },
    [onClickLink]
  );

  React.useEffect(() => {
    if (selectorRef.current) {
      wrapInSpans(selectorRef.current, classes.highlight, onClickLink);
    }
  }, [classes.highlight, selectorRef, onClickLink]);

  React.useEffect(() => {
    selectorRef!
      .current!.querySelectorAll(`.${classes.highlight}`)
      .forEach((e: any) => {
        e.addEventListener("mouseup", handleSelection);
      });
    selectorRef!
      .current!.querySelectorAll(`a`)
      .forEach((a: HTMLAnchorElement) => {
        a.addEventListener("click", handleLink(a));
      });
    return () => {
      selectorRef!
        .current!.querySelectorAll(`.${classes.highlight}`)
        .forEach((e: any) => {
          e.removeEventListener("mouseup", handleSelection);
        });
      selectorRef!
        .current!.querySelectorAll(`a`)
        .forEach((a: HTMLAnchorElement) => {
          a.removeEventListener("click", handleLink(a));
        });
    };
  }, [handleSelection, handleLink, classes.highlight, selectorRef]);
}
乔丹·伯内特

每次调用时,handleLink(a)您都将创建一个新的匿名函数用作事件处理程序的回调。

调用时,removeEventListener您应该传递对用于附加事件的同一回调的引用,但是,每次调用时,handleLink您都在创建一个新的匿名函数。

您可以以某种方式存储对您所创建或重写的回调的引用,handleLink从而根本不需要传递该元素。

const handleLink = React.useCallback((e: MouseEvent) => {
    e.preventDefault();
    onClickLink(e.currentTarget.href);
}, [onClickLink]);

...

React.useEffect(() => {
  selectorRef!
    .current!.querySelectorAll(`.${classes.highlight}`)
    .forEach((e: any) => {
      e.addEventListener("mouseup", handleSelection);
    });
  selectorRef!
    .current!.querySelectorAll(`a`)
    .forEach((a: HTMLAnchorElement) => {
      a.addEventListener("click", handleLink);
    });
  return () => {
    selectorRef!
      .current!.querySelectorAll(`.${classes.highlight}`)
      .forEach((e: any) => {
        e.removeEventListener("mouseup", handleSelection);
      });
    selectorRef!
      .current!.querySelectorAll(`a`)
      .forEach((a: HTMLAnchorElement) => {
        a.removeEventListener("click", handleLink);
      });
  };
}, [handleSelection, handleLink, classes.highlight, selectorRef]);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Y滚动事件侦听器useEffect

来自分类Dev

removeEventListener不会删除侦听器

来自分类Dev

无法删除(绑定的)事件侦听器

来自分类Dev

删除Dojo dGrid的事件侦听器

来自分类Dev

电子:删除beforeunload事件侦听器

来自分类Dev

Javascript删除“焦点”事件侦听器

来自分类Dev

无法删除(绑定的)事件侦听器

来自分类Dev

删除事件侦听器as3

来自分类Dev

无法删除事件侦听器

来自分类Dev

无法删除 touchmove 事件侦听器

来自分类Dev

删除类不会禁用与删除的类关联的事件侦听器功能

来自分类Dev

如果我只知道元素和事件,请删除事件侦听器

来自分类Dev

反应useEffect不清除事件侦听器

来自分类Dev

我需要在2016年删除事件侦听器吗?

来自分类Dev

删除元素还会删除其事件侦听器吗?

来自分类Dev

删除子功能事件侦听器

来自分类Dev

如何删除Aurelia中的事件侦听器?

来自分类Dev

无法删除CSS动画结束的事件侦听器

来自分类Dev

删除用于带节流功能的Scroll事件侦听器

来自分类Dev

reactjs事件侦听器beforeunload添加但未删除

来自分类Dev

如何删除在TypeScript中使用“ this”的事件侦听器?

来自分类Dev

更新或更改或删除/重置Javascript事件侦听器

来自分类Dev

无法删除事件侦听器TypeScript / OOP JavaScript

来自分类Dev

创建事件侦听器以从localStorage删除对象

来自分类Dev

最佳实践的确认:删除事件侦听器

来自分类Dev

删除一组事件侦听器

来自分类Dev

未删除事件侦听器-点亮的元素

来自分类Dev

如何删除从各个要素动态创建的事件侦听器?

来自分类Dev

如何在EaselJS对象中删除事件侦听器