Раскрывающиеся меню — это распространенный элемент пользовательского интерфейса в веб-приложениях, предоставляющий удобный способ представления пользователю списка опций. Одним из распространенных требований к раскрывающимся спискам является их закрытие, когда пользователь щелкает за пределами области раскрывающегося списка. В этой статье мы рассмотрим различные методы достижения такого поведения в React, а также приведем примеры кода.
Метод 1: прослушиватель событий в документе.
Один простой подход — прикрепить прослушиватель событий к объекту documentи проверить, возникло ли событие щелчка извне компонента раскрывающегося списка. Вот пример реализации:
import React, { useRef, useEffect } from 'react';
const Dropdown = () => {
const dropdownRef = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
// Close the dropdown
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, []);
return (
<div ref={dropdownRef}>
{/* Dropdown content */}
</div>
);
};
export default Dropdown;
Метод 2: прослушиватель событий в родительском компоненте
Другой подход — прикрепить прослушиватель событий к родительскому компоненту раскрывающегося списка. Этот метод обеспечивает большую гибкость, если на одной странице имеется несколько раскрывающихся списков. Вот пример:
import React, { useRef, useEffect } from 'react';
const ParentComponent = () => {
const dropdownRef = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
// Close the dropdown
}
};
const handleKeyDown = (event) => {
if (event.key === 'Escape') {
// Close the dropdown
}
};
document.addEventListener('click', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('click', handleClickOutside);
document.removeEventListener('keydown', handleKeyDown);
};
}, []);
return (
<div>
{/* Other components */}
<Dropdown ref={dropdownRef} />
{/* Other components */}
</div>
);
};
export default ParentComponent;
Метод 3: React Portal
React Portal позволяет отображать дерево DOM компонента в другом месте иерархии DOM. Отрисовывая раскрывающийся список за пределами его родительского компонента, вы можете легче обрабатывать щелчки за пределами раскрывающегося списка. Вот пример:
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
const Dropdown = () => {
const [isOpen, setIsOpen] = useState(false);
const handleOutsideClick = () => {
setIsOpen(false);
};
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
{isOpen &&
ReactDOM.createPortal(
<div onClick={handleOutsideClick}>
{/* Dropdown content */}
</div>,
document.body
)}
</>
);
};
export default Dropdown;
В этой статье мы рассмотрели три различных метода закрытия раскрывающегося списка React при нажатии снаружи. Независимо от того, решите ли вы использовать прослушиватель событий в документе или родительском компоненте или использовать порталы React, эти методы предоставляют эффективные решения для улучшения взаимодействия с пользователем. Не забудьте учитывать ваш конкретный вариант использования и выбрать метод, который лучше всего соответствует требованиям вашего приложения.