ClickAwayListener — это компонент из библиотеки MUI,
предназначенный для обработки событий клика вне определённого элемента.
Он особенно полезен при реализации выпадающих меню, модальных окон,
подсказок и других компонентов, которые должны закрываться при клике вне
их области. Основная идея заключается в «слушании» событий клика на
документе и вызове функции обратного вызова, если клик произошёл за
пределами дочернего элемента.
Для работы с ClickAwayListener требуется импортировать
его из пакета @mui/material:
import ClickAwayListener from '@mui/material/ClickAwayListener';
Базовый синтаксис компонента выглядит следующим образом:
<ClickAwayListener onClickA way={handleClickAway}>
<div>
{/* Контент, для которого нужен контроль кликов вне области */}
</div>
</ClickAwayListener>
children) — единственный React-узел,
за клики вне которого будет отслеживаться событие.Пример простого применения:
import React, { useState } from 'react';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import Button from '@mui/material/Button';
import Paper from '@mui/material/Paper';
function DropdownExample() {
const [open, setOpen] = useState(false);
const handleClick = () => {
setOpen((prev) => !prev);
};
const handleClickAway = () => {
setOpen(false);
};
return (
<ClickAwayListener onClickA way={handleClickAway}>
<div>
<Button onCl ick={handleClick}>Открыть меню</Button>
{open ? (
<Paper elevation={3} style={{ marginTop: 8, padding: 16 }}>
Содержимое меню
</Paper>
) : null}
</div>
</ClickAwayListener>
);
}
В этом примере клик по кнопке открывает меню, а клик за пределами
области Paper закрывает его.
Иногда необходимо игнорировать клики на некоторых дочерних элементах
или контролировать обработку событий более точно. В таких случаях
используется комбинация event.stopPropagation() и условной
логики внутри onClickAway.
Пример игнорирования клика на кнопке внутри области:
const handleClickAway = (event) => {
if (event.target.closest('.ignore-click')) {
return;
}
setOpen(false);
};
<div className="ignore-click">
<Button>Не закрывать меню при клике</Button>
</div>
Использование closest позволяет проверять, принадлежит
ли кликнутый элемент определённому селектору, и избежать нежелательного
закрытия.
ClickAwayListener предоставляет дополнительные параметры
для более гибкой настройки:
'onClick', 'onMouseDown',
'onMouseUp' или false). По умолчанию
'onClick'.'onTouchStart', 'onTouchEnd' или
false). По умолчанию 'onTouchEnd'.Пример с отключением стандартного события мыши:
<ClickAwayListener onClickA way={handleClickAway} mouseEvent="onMouseDown">
<Paper>
Контент
</Paper>
</ClickAwayListener>
В случаях, когда дочерний элемент рендерится через портал
(ReactDOM.createPortal) или Popper,
стандартное поведение ClickAwayListener может не срабатывать, так как
элемент физически находится вне React-дерева. Решение — использовать
disableReactTree={true}, чтобы компонент слушал все клики
документа:
<ClickAwayListener onClickA way={handleClickAway} disableReactTree>
<Popper open={open} anchorEl={anchorEl}>
<Paper>Меню с порталом</Paper>
</Popper>
</ClickAwayListener>
ClickAwayListener
корректно определял границы.ClickAwayListener к каждому элементу внутри меню;
достаточно одного на родительском контейнере.onClickAway позволяет централизованно
управлять видимостью элементов интерфейса.ClickAwayListener отлично сочетается с:
Пример использования с Popover:
<ClickAwayListener onClickA way={handleClickAway}>
<Popover
open={open}
anchorEl={anchorEl}
onCl ose={handleClickAway}
>
<Paper style={{ padding: 16 }}>Контент Popover</Paper>
</Popover>
</ClickAwayListener>
ClickAwayListener реагирует на клики вне дочернего
элемента и вызывает onClickAway.disableReactTree.Эта функциональность делает ClickAwayListener
незаменимым инструментом при построении интерактивных интерфейсов на
основе MUI, обеспечивая корректное поведение компонентов при
взаимодействии пользователя с документом.