反应。防止双击时发生点击事件

问题描述 投票:0回答:2

我正在尝试实现一个计时器来区分单击和双击事件,这样当双击时单击不会触发。

编辑:我应该澄清一下,我希望组件对单击/双击做出不同的反应,双击正在工作,但是当我双击时,它也会触发单击事件。我想在双击时忽略单击


export const useNoClickOnDblClick = (onClick: () => void, onDoubleClick: () => void) => {
  const [clicks, setClicks] = useState(0);

  useEffect(() => {
    let singleClickTimer: string | number | NodeJS.Timeout | undefined;
    if (clicks === 1) {
      singleClickTimer = setTimeout(function () {
        onClick();
        setClicks(0);
      }, 250);
    } else if (clicks === 2) {
      onDoubleClick();
      setClicks(0);
    }
    return () => clearTimeout(singleClickTimer);
  }, [clicks]);

  return {
    clicks,
    setClicks
  };
};

不确定这是否是最好的方法,但我在该线程底部附近遇到了这个实现,https://github.com/facebook/react/issues/3185

它似乎适用于基本用法,没有参数的函数,如下所示


  const { setClicks } = useNoClickOnDblClick(handleRenderInfo, () => console.log('dbl click'));


 <SummaryCard
   data={data}
   onCardClick={() => setClicks((prev) => prev + 1)}
 />

但是我想做这样的事情,我需要为每张卡传递不同的数据


 const { setClicks } = useNoClickOnDblClick(handleRenderLevelInfo, () => console.log('dbl click'));

{mineData.levelArr.map((level, i) => {
        return (
          <MineCard
            key={i}
            data={level}
            onCardClick={() => setClicks((prev) => prev + 1)}
            //onCardClick={() => handleRenderLevelInfo({ ...level, idx: i })}
            onCardDblClick={() =>
              navigateTo({ path: `/${surveyPointsPrefix}/${mineID}/${level.level}` })
            }
          />
        );
      })}

如何从 .map 传入关卡数据?我知道我可以通过单击/双击将整个内容传递到 customHook 中,但我觉得如果我尝试重用钩子等,它会变得非常混乱。

感谢您的帮助。

reactjs double-click react-custom-hooks
2个回答
0
投票
singleClickMethod () {};
doubleClickMethod () {};

hasDoubleClick = false:

onClickHandler (event) {
    event.preventDefault();
    event.stopPropagation();

    setTimeout(() => {
        if (hasDoubleClick) {
            hasDoubleClick = false;
            return;
        }

        singleClickMethod();
    });
};

onDblClickHandler () {
    hasDoubleClick = true;

    doubleClickMethod();
}

这种方法将对您有用并区分点击事件。


0
投票

您可以使用此自定义挂钩:

export const useDoubleClick = (onClick, onDbClick, delay = 300) => {
  const timePassed= useRef(0);
  return (e: MouseEvent) => {
   if (e.detail === 1) {
     setTimeout(() => {
       if (Date.now() - timePassed.current >= delay) {
         onClick();
       }
     }, delay)
   }

   if (e.detail === 2) {
     timePassed.current = Date.now();
     onDbClick();
   }
 }
}

然后像这样使用它:

const onClick = () => console.log('click')
const onDoubleClick = () => console.log('double click')

const myDoubleClickCallback = useDoubleClick(onClick, onDoubleClick);

并将 myDoubleClickCallback 添加到组件中:

<div onClick={myDoubleClickCallback}>Click Me</div>
© www.soinside.com 2019 - 2024. All rights reserved.