useClick — это хук, предоставляемый библиотекой Floating
UI, который позволяет управлять открытием и закрытием всплывающих
элементов (popper, tooltip, dropdown и т. д.) при клике на
элемент-источник (reference element). Он реализует удобный и гибкий
способ обработки кликов без необходимости вручную подписываться на
события DOM.
Для начала необходимо подключить хук из пакета:
import { useClick } from '@floating-ui/react';
useClick возвращает объект с настройками и обработчиками
событий, которые интегрируются с другими хуками Floating UI, такими как
useFloating.
Простейший пример:
import { useFloating, useClick } from '@floating-ui/react';
import { useRef } from 'react';
function Dropdown() {
const { x, y, reference, floating, strategy } = useFloating();
const click = useClick({ open: false });
return (
<>
<button ref={reference} onCl ick={click.onClick}>Открыть меню</button>
{click.open && (
<div ref={floating} style={{ position: strategy, top: y ?? 0, left: x ?? 0 }}>
Содержимое меню
</div>
)}
</>
);
}
Здесь ключевые моменты:
reference – ссылка на элемент, по которому
отслеживается клик.floating – ссылка на всплывающий элемент.click.open – булевый флаг состояния видимости.click.onClick – обработчик события клика, который
автоматически переключает состояние open.useClick принимает объект конфигурации с несколькими
важными опциями:
const click = useClick({
open: false, // начальное состояние (открыто/закрыто)
toggle: true, // переключение состояния при повторном клике
enabled: true, // включение или отключение обработки клика
ignoreMouse: false, // игнорировать клики мыши (например, при мобильных устройствах)
});
toggle – если true,
повторный клик закрывает всплывающий элемент.enabled – можно динамически отключать
хук, оставляя элемент статичным.ignoreMouse – полезно при
необходимости управлять открытием через клавиатуру или другие
события.Чаще всего useClick используется совместно с:
useFloating – основной хук для позиционирования
всплывающего элемента.useDismiss – для закрытия элемента при клике вне зоны
или при нажатии Escape.useInteractions – объединяет несколько хуков в один
объект обработчиков.Пример комплексного использования:
import { useFloating, useClick, useDismiss, useInteractions } from '@floating-ui/react';
function Menu() {
const { x, y, reference, floating, strategy } = useFloating();
const click = useClick({ open: false });
const dismiss = useDismiss({ outsidePress: true });
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]);
return (
<>
<button ref={reference} {...getReferenceProps()}>Меню</button>
{click.open && (
<div ref={floating} style={{ position: strategy, top: y ?? 0, left: x ?? 0 }} {...getFloatingProps()}>
Элементы меню
</div>
)}
</>
);
}
Здесь useInteractions автоматически комбинирует события
click и dismiss, позволяя не заботиться о
конфликте обработчиков.
useClick может вести себя
иначе из-за особенностей события touchstart.ignoreMouse помогает отключить поведение мыши,
если требуется управлять открытием через касания.open извне, передавая его через пропсы и
обновляя вручную:const [isOpen, setIsOpen] = useState(false);
const click = useClick({ open: isOpen, toggle: true });
<button
ref={reference}
onKeyD own={(e) => {
if (e.key === 'Enter') click.onClick(e);
}}
>
Открыть меню
</button>
const click = useClick({ enabled: !isLoading });
useClick с useDismiss для
удобного закрытия при клике вне зоны.useInteractions, чтобы объединять
несколько хуков и минимизировать конфликт обработчиков.toggle и open при
динамическом контенте, чтобы избежать мерцания или некорректного
позиционирования.useClick обеспечивает гибкое управление интерактивными
всплывающими элементами, минимизируя необходимость ручной работы с
событиями DOM и позволяя легко интегрировать динамическое отображение
контента с точным позиционированием через Floating UI.