Передача данных в модальные окна

Ant Design предоставляет мощный компонент Modal, позволяющий создавать диалоговые окна для подтверждений, форм и различных пользовательских интерфейсов. Одной из ключевых задач при работе с модальными окнами является передача данных из родительского компонента в модальное окно и обработка этих данных внутри него. Рассмотрим основные подходы и практические примеры.


Управление состоянием модального окна

В Ant Design модальные окна управляются через проп visible (или open в новых версиях) и события onOk и onCancel. Для передачи данных важно правильно структурировать состояние.

import React, { useState } from 'react';
import { Modal, Button } from 'antd';

const App = () => {
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalData, setModalData] = useState(null);

  const showModal = (data) => {
    setModalData(data);
    setIsModalVisible(true);
  };

  const handleOk = () => {
    console.log('Данные из модального окна:', modalData);
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  return (
    <>
      <Button onCl ick={() => showModal({ id: 1, name: 'Тест' })}>Открыть модалку</Button>
      <Modal
        title="Информация"
        open={isModalVisible}
        onOk={handleOk}
        onCan cel={handleCancel}
      >
        <p>ID: {modalData?.id}</p>
        <p>Имя: {modalData?.name}</p>
      </Modal>
    </>
  );
};

export default App;

Ключевые моменты:

  • Создаётся состояние modalData, которое хранит данные для модального окна.
  • Функция showModal принимает объект данных и открывает окно.
  • Использование опциональной цепочки (?.) позволяет безопасно обращаться к данным до их передачи.

Передача сложных объектов и форм

Модальные окна часто содержат формы, которые необходимо предварительно заполнить данными. Ant Design предоставляет компонент Form, который легко интегрируется с Modal.

import React, { useState } from 'react';
import { Modal, Button, Form, Input } from 'antd';

const UserModal = ({ visible, onCancel, initialValues, onSubmit }) => {
  const [form] = Form.useForm();

  const handleOk = () => {
    form.validateFields()
      .then(values => {
        onSubmit(values);
      })
      .catch(info => {
        console.log('Ошибка валидации:', info);
      });
  };

  return (
    <Modal
      title="Редактировать пользователя"
      open={visible}
      onOk={handleOk}
      onCan cel={onCancel}
    >
      <Form form={form} initialValues={initialValues} layout="vertical">
        <Form.Item name="name" label="Имя" rules={[{ required: true, message: 'Введите имя' }]}>
          <Input />
        </Form.Item>
        <Form.Item name="email" label="Email" rules={[{ required: true, type: 'email', message: 'Введите корректный email' }]}>
          <Input />
        </Form.Item>
      </Form>
    </Modal>
  );
};

const App = () => {
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [user, setUser] = useState({ name: 'Иван', email: 'ivan@example.com' });

  return (
    <>
      <Button onCl ick={() => setIsModalVisible(true)}>Редактировать пользователя</Button>
      <UserModal
        visible={isModalVisible}
        initialValues={user}
        onCan cel={() => setIsModalVisible(false)}
        onSub mit={(values) => {
          console.log('Обновлённые данные пользователя:', values);
          setUser(values);
          setIsModalVisible(false);
        }}
      />
    </>
  );
};

export default App;

Важные моменты:

  • initialValues позволяет передавать данные в форму сразу при её рендеринге.
  • Форма внутри модального окна может использовать методы form.validateFields() для проверки данных перед закрытием.
  • Передача функции onSubmit обеспечивает обратную связь с родителем и обновление состояния.

Использование контекста для передачи данных

В больших приложениях, где данные используются в нескольких модальных окнах, удобно применять React Context. Это позволяет избежать передачи пропсов через цепочку компонентов.

import React, { createContext, useContext, useState } from 'react';
import { Modal, Button } from 'antd';

const ModalContext = createContext();

const ModalProvider = ({ children }) => {
  const [modalData, setModalData] = useState(null);
  const [isVisible, setIsVisible] = useState(false);

  const openModal = (data) => {
    setModalData(data);
    setIsVisible(true);
  };

  const closeModal = () => setIsVisible(false);

  return (
    <ModalContext.Provider value={{ modalData, isVisible, openModal, closeModal }}>
      {children}
    </ModalContext.Provider>
  );
};

const CustomModal = () => {
  const { isVisible, closeModal, modalData } = useContext(ModalContext);

  return (
    <Modal
      title="Детали"
      open={isVisible}
      onCan cel={closeModal}
      onOk={closeModal}
    >
      <p>ID: {modalData?.id}</p>
      <p>Название: {modalData?.name}</p>
    </Modal>
  );
};

const App = () => {
  const { openModal } = useContext(ModalContext);

  return (
    <Button onCl ick={() => openModal({ id: 5, name: 'Продукт A' })}>
      Показать модалку
    </Button>
  );
};

export default () => (
  <ModalProvider>
    <App />
    <CustomModal />
  </ModalProvider>
);

Преимущества подхода с контекстом:

  • Центральное управление состоянием всех модальных окон.
  • Упрощение передачи данных в компоненты, находящиеся глубоко в дереве.
  • Лёгкая масштабируемость при добавлении новых модальных окон и типов данных.

Динамическая генерация модальных окон

Иногда требуется создавать модальные окна динамически с разными компонентами и данными. Ant Design позволяет использовать Modal.confirm и Modal.info для таких задач:

import { Modal, Button } from 'antd';

const showDynamicModal = (data) => {
  Modal.info({
    title: 'Динамическое окно',
    content: (
      <div>
        <p>ID: {data.id}</p>
        <p>Описание: {data.description}</p>
      </div>
    ),
    onOk() {},
  });
};

<Button onCl ick={() => showDynamicModal({ id: 10, description: 'Тестовая задача' })}>
  Показать динамическую модалку
</Button>

Особенности:

  • Модальные окна создаются без необходимости включения состояния в компонент.
  • Удобно для всплывающих уведомлений или быстрых диалогов подтверждения.
  • Можно передавать любые данные через объект data.

Рекомендации по организации передачи данных

  1. Использовать state для простых случаев — когда данные нужны только текущему компоненту.
  2. Передавать initialValues для форм — упрощает редактирование и валидацию данных.
  3. Применять Context для глобальных данных — подходит для крупных приложений с множеством модальных окон.
  4. Использовать динамические модальные окна для одноразовых уведомлений и подтверждений.
  5. Следить за безопасным доступом к данным — использовать опциональную цепочку или дефолтные значения, чтобы избежать ошибок рендера.

Эти подходы обеспечивают гибкость и масштабируемость при работе с модальными окнами в Ant Design, позволяя передавать данные эффективно и безопасно.