自定义钩子,用于将事件监听器附加到使用useRef?

时间:2019-05-14 17:41:31

标签: javascript reactjs react-hooks

我正在构建一个名为 useSwipe 的自定义钩子,该钩子必须为touchstarttouchmovetouchend 添加事件处理程序 HTML元素,使用useRef()钩子将其存储为 ref 。触发这些事件后,还应执行回调

我的组件

function Component() {
  const divRef = useRef(null);  // The ref for the element

  useSwipe(divRef.current,someFunction);

  function someFunction() {
    console.log('Something happened...');
  }

  return (
    <div ref={divRef}>
      Some Content
    </div>
  );
}

自定义挂钩:useSwipe.js

import {useEffect, useRef} from 'react';

function useSwipe(element, callback) {

useEffect(() => {

  function onTouchStart() {
    callback();
  }
  function onTouchMove() {
    callback();
  }
  function onTouchEnd() {
    callback();
  }

  if (element !== null) {
      element.addEventListener('touchstart', onTouchStart);
      element.addEventListener('touchmove', onTouchMove);
      element.addEventListener('touchend', onTouchEnd);
  }

  return () => {
      if (element !== null) {
        console.log('useSwipe useEffect return...');
        element.removeEventListener('touchstart', onTouchStart);
        element.removeEventListener('touchmove', onTouchMove);
        element.removeEventListener('touchend', onTouchEnd);
      }
  };

});

}

export default useSwipe;

问题

在每个渲染器上添加和删除事件侦听器是一种不好的做法吗?它会影响性能吗?

我可以在element的依赖项数组中添加callbackuseEffect(),如下所示,但是由于回调将在每个渲染器上改变(在我的情况下),结果将是相同。我将在每个渲染器上添加和删除侦听器。

useEffect(()=>{},[element,callback]);

我是否有办法在安装时仅一次添加那些事件侦听器,而在卸载时将其删除呢?我想不出办法,因为每次尝试这样做时,我都会获得过时的处理程序版本(由于它们会收到新的callbacks而需要更新。因此,我最终重新创建了所有内容:处理程序和侦听器。

0 个答案:

没有答案