Modal.tsx

Обзор

Файл Modal.tsx содержит React-компонент модального окна, предназначенного для отображения контента поверх основного интерфейса приложения. Основная задача компонента — обеспечить удобный и доступный способ отображения всплывающих окон с возможностью закрытия по клику вне окна или нажатию клавиши Escape. Компонент поддерживает заголовок, пользовательский контент и кастомизацию через передаваемые свойства.


Подробное описание

Интерфейс ModalProps

Определяет свойства, принимаемые компонентом Modal.

Свойство

Тип

Обязательное

Описание

isOpen

boolean

Да

Флаг, указывающий открыт ли модал.

onClose

() => void

Да

Функция обратного вызова для закрытия модала.

title

string

Нет

Заголовок модального окна.

children

React.ReactNode

Да

Контент, отображаемый внутри модального окна.

className

string

Нет

Дополнительный CSS-класс для кастомизации.


Компонент Modal

Функциональный React-компонент, реализующий модальное окно.

Параметры

Возвращаемое значение

Возвращает JSX элемент модального окна при isOpen === true. При isOpen === false возвращает null, то есть ничего не рендерит.

Основная логика

  1. Обработчик клавиши Escape
    При монтировании и обновлении компонента добавляется обработчик события keydown на документ, который вызывает onClose, если нажата клавиша Escape и модал открыт. Обработчик удаляется при размонтировании.

  2. Управление классом modal-open у body
    При открытии модала к тегу <body> добавляется класс modal-open, что позволяет, например, блокировать скролл страницы. При закрытии класс удаляется.

  3. Обработка кликов

    • Клик по затемнённой области (оверлею) вызывает onClose, закрывая окно.

    • Клик внутри модального окна не распространяется (используется stopPropagation()), чтобы избежать закрытия.

  4. Отрисовка

    • Если передан title, он отображается в отдельном блоке с классом modal-title.

    • Основной контент — children — рендерится внутри.


Пример использования

import React, { useState } from 'react';
import Modal from './Modal';

const App = () => {
  const [isModalOpen, setModalOpen] = useState(false);

  return (
    <>
      <button onClick={() => setModalOpen(true)}>Открыть модал</button>
      <Modal
        isOpen={isModalOpen}
        onClose={() => setModalOpen(false)}
        title="Пример модального окна"
        className="custom-modal"
      >
        <p>Это содержимое модального окна.</p>
      </Modal>
    </>
  );
};

Важные детали реализации


Взаимодействие с другими частями системы


Диаграмма структуры компонента

componentDiagram
    component Modal {
        +isOpen: boolean
        +onClose(): void
        +title?: string
        +children: ReactNode
        +className?: string
        --
        useEffect(handleEscape)
        useEffect(toggleBodyClass)
        render()
    }
    Modal --> React

Итог

Modal.tsx — это универсальный, лёгкий и расширяемый React-компонент модального окна. Он обеспечивает удобный интерфейс взаимодействия с пользователем, поддерживает закрытие по клавише Escape и клику вне окна, а также позволяет кастомизировать внешний вид через CSS. Благодаря грамотной реализации побочных эффектов и управлению событиями, компонент легко интегрируется в различные части приложения, улучшая UX за счёт модальных диалогов.