Эффективные методы закрытия раскрывающегося списка React при нажатии снаружи

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