useClick хук

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 – полезно при необходимости управлять открытием через клавиатуру или другие события.

Интеграция с другими хуками Floating UI

Чаще всего 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 помогает отключить поведение мыши, если требуется управлять открытием через касания.
  • Важно учитывать задержку реакции на касание и тестировать на реальных устройствах, чтобы избежать двойного срабатывания.

Расширенные сценарии использования

  1. Контролируемое состояние: Можно полностью управлять состоянием open извне, передавая его через пропсы и обновляя вручную:
const [isOpen, setIsOpen] = useState(false);
const click = useClick({ open: isOpen, toggle: true });
  1. Комбинация с клавиатурой: Для доступности можно добавить обработку клавиш, например, открытие по Enter или Space:
<button
  ref={reference}
  onKeyD own={(e) => {
    if (e.key === 'Enter') click.onClick(e);
  }}
>
  Открыть меню
</button>
  1. Динамическое отключение: Можно отключить хук при определённых условиях, например, когда всплывающий элемент загружает данные:
const click = useClick({ enabled: !isLoading });

Практические рекомендации

  • Всегда сочетать useClick с useDismiss для удобного закрытия при клике вне зоны.
  • Использовать useInteractions, чтобы объединять несколько хуков и минимизировать конфликт обработчиков.
  • Тестировать поведение на мобильных устройствах и планшетах для корректной работы touch-событий.
  • Контролировать toggle и open при динамическом контенте, чтобы избежать мерцания или некорректного позиционирования.

useClick обеспечивает гибкое управление интерактивными всплывающими элементами, минимизируя необходимость ручной работы с событиями DOM и позволяя легко интегрировать динамическое отображение контента с точным позиционированием через Floating UI.