В библиотеке Chakra UI управление кликами вне
компонента реализуется с помощью хука useOutsideClick. Этот
инструмент позволяет отслеживать события клика за пределами указанного
элемента и выполнять определённое действие, например, закрытие
модального окна, выпадающего меню или тултипа.
Для работы с useOutsideClick необходимо импортировать
хук из пакета @chakra-ui/react:
import { useRef } from "react";
import { useOutsideClick, Box } from "@chakra-ui/react";
Создание базового элемента с обработкой клика вне:
function Dropdown() {
const ref = useRef();
useOutsideClick({
ref: ref,
handler: () => {
console.log("Клик вне элемента");
},
});
return (
<Box ref={ref} p={4} bg="teal.100" w="200px">
Контент выпадающего меню
</Box>
);
}
Пояснение ключевых моментов:
ref – ссылка на DOM-элемент, за пределами которого
необходимо отслеживать клики.handler – функция, вызываемая при обнаружении клика вне
элемента, на который ссылается ref.mousedown и touchstart, что обеспечивает
корректную работу как для мыши, так и для сенсорных устройств.Применение useOutsideClick в сочетании с модальными
компонентами позволяет закрывать окно при клике вне области модалки:
import { Modal, ModalContent, ModalOverlay } from "@chakra-ui/react";
function CustomModal({ isOpen, onClose }) {
const ref = useRef();
useOutsideClick({
ref: ref,
handler: onClose,
});
if (!isOpen) return null;
return (
<Modal isOpen={isOpen} onCl ose={onClose}>
<ModalOverlay />
<ModalContent ref={ref} p={6}>
Содержимое модального окна
</ModalContent>
</Modal>
);
}
Особенности:
ModalContent оборачивается в ref, чтобы
useOutsideClick отслеживал именно область модального
окна.onClose вызывается только при клике вне модалки, что
предотвращает закрытие при взаимодействии с внутренним контентом.Часто требуется интеграция с состояниями React для управления видимостью компонентов:
import { useState } from "react";
import { Button, Box } from "@chakra-ui/react";
function Popover() {
const [isOpen, setIsOpen] = useState(false);
const ref = useRef();
useOutsideClick({
ref: ref,
handler: () => setIsOpen(false),
});
return (
<Box>
<Button onCl ick={() => setIsOpen(!isOpen)}>Открыть поповер</Button>
{isOpen && (
<Box ref={ref} mt={2} p={4} bg="gray.100" borderRadius="md">
Содержимое поповера
</Box>
)}
</Box>
);
}
Ключевые моменты:
useState позволяет
комбинировать useOutsideClick с условным рендерингом.handler состояние
обновляется, что автоматически убирает элемент из DOM.Если внутри отслеживаемого компонента есть вложенные интерактивные
элементы, важно использовать один ref на общий контейнер,
чтобы клики внутри него не вызывали закрытие:
<Box ref={ref} p={4} bg="blue.50">
<Button onCl ick={() => alert("Внутренний клик")}>Кнопка</Button>
<Input placeholder="Текстовое поле" mt={2} />
</Box>
useOutsideClick корректно обрабатывает клики на
вложенные элементы и не срабатывает, пока клик находится внутри
ref.
useRef только на
элемент-контейнер, а не на каждую внутреннюю часть, чтобы
избежать лишних обработчиков.handler,
особенно если они тяжелые, чтобы не снижать производительность при
каждом клике.useState или
useDisclosure, встроенным хук-менеджером Chakra UI
для управления состояниями видимости компонентов.touchstart.В Chakra UI для компонентов типа Drawer,
Modal, Popover часто применяется хук
useDisclosure, который в сочетании с
useOutsideClick позволяет легко управлять открытием и
закрытием элементов. Пример:
import { useDisclosure, Box } from "@chakra-ui/react";
const { isOpen, onOpen, onClose } = useDisclosure();
С этим хуком код становится чище, а логика клика вне компонента
интегрируется прямо в состояние isOpen.
Хук useOutsideClick является мощным инструментом для
управления интерактивными компонентами в Chakra UI. Он обеспечивает
надежное закрытие выпадающих элементов, поповеров и модальных
окон, корректно работает с вложенными элементами и мобильными
устройствами, а также легко интегрируется с управлением состоянием через
React.