react Обработать двойной клик, если он сделан, без обработки одинарного double click / click
Primary tabs
Для обработки отдельно одинарного и двойного клика, можно использовать такой пользовательский хук:
import { useMemo, useRef } from 'react'; export type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void; export function useClickAndDoubleClickHandler(onSingleClick: ClickHandler, onDoubleClick: ClickHandler, latency = 250) { const clickCount = useRef(0); const clickHandler = useMemo(() => { return (event: React.MouseEvent<HTMLElement>) => { clickCount.current += 1; setTimeout(function () { if (clickCount.current === 1) { onSingleClick(event); } else if (clickCount.current === 2) { onDoubleClick(event); } clickCount.current = 0; }, latency); }; }, [onSingleClick, onDoubleClick, latency]); return clickHandler; }
Идея (использование общего обработчика с таймаутом, замкнутого на переменную из внешней области видимости) взята из реализации use-double-click , но в отличие от нее:
- кеширует обработчик через useMemo()
- не использует useEffect, чтобы позволяет, если требуется не рендерить элемент, на который вы ставите обработчик а также в целом уйти от установки/прокидывания рефов.
Какие еще варианты
Какие есть варианты (оба связаны искусственной с задержкой обработки одинарного клика):
- Сделать свой промис, опираясь на который ждать в одинарном клике, не будет ли он отменен в в обработчике двойного клика. Внимательно этот вариант не изучался
- Использовать готовое решение - пользовательский хук для того же самого, например, use-double-click
Минусом в реализации use-double-click является то, что эта реализация опирается внутри на useEffect и в любом случае будет пытаться поставить обработчик, что приведет к ошибке, если вы так и не отрендерите свой копонент очередной раз (напр, потому что текст, по которому вы делаете двойной клик, заменился на поле ввода) -- решить этом можно с помощью подхода/кода в начале этой заметки
-- может есть, что еще, но в нашем случае пока что успели рассмотреть только эти решения
- Log in to post comments
- 1342 reads