Модальные окна в Ant Design (Modal)
предоставляют гибкий инструмент для отображения диалогов с
пользователем. Одним из ключевых аспектов работы с модальными окнами
является управление асинхронными операциями, такими как
запросы к серверу, задержки или обработка данных перед закрытием окна.
Понимание правильного подхода к асинхронности позволяет создавать
интерфейсы с отзывчивой логикой и корректным пользовательским
опытом.
okButtonProps и confirmLoadingКомпонент Modal поддерживает встроенную интеграцию с
асинхронными действиями через свойство
confirmLoading. Оно предназначено для
отображения состояния загрузки на кнопке подтверждения (OK), пока
выполняется асинхронная операция.
Пример:
import React, { useState } from 'react';
import { Modal, Button, message } from 'antd';
const AsyncModalExample = () => {
const [visible, setVisible] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const handleOk = async () => {
setConfirmLoading(true);
try {
await new Promise(resolve => setTimeout(resolve, 2000)); // эмуляция запроса
message.success('Операция завершена успешно');
setVisible(false);
} catch (error) {
message.error('Произошла ошибка');
} finally {
setConfirmLoading(false);
}
};
return (
<>
<Button type="primary" onCl ick={() => setVisible(true)}>
Открыть модальное окно
</Button>
<Modal
title="Асинхронная операция"
visible={visible}
onOk={handleOk}
confirmLoading={confirmLoading}
onCan cel={() => setVisible(false)}
>
<p>Нажмите "OK" для запуска асинхронной операции.</p>
</Modal>
</>
);
};
export default AsyncModalExample;
Особенности данного подхода:
confirmLoading управляет состоянием кнопки OK, блокируя
повторные клики.handleOk позволяет безопасно
обрабатывать промисы и отображать уведомления о результате.setVisible(false)) происходит
только после завершения операции.Иногда необходимо выполнить валидацию или асинхронный запрос перед закрытием окна, не блокируя интерфейс. Для этого можно использовать подход с ручным управлением видимостью и состоянием загрузки.
const handleOk = async () => {
setConfirmLoading(true);
try {
const result = await fetch('/api/save', { method: 'POST' });
if (!result.ok) throw new Error('Ошибка сохранения');
setVisible(false);
message.success('Данные успешно сохранены');
} catch (err) {
message.error(err.message);
} finally {
setConfirmLoading(false);
}
};
Ключевые моменты:
setVisible(false) не вызван.confirmLoading улучшает UX,
показывая пользователю, что операция в процессе.Form внутри модального окна с асинхронной отправкойЧастый сценарий — форма внутри модального окна, где кнопка OK выполняет асинхронную отправку данных.
import { Form, Input } from 'antd';
const FormModal = () => {
const [visible, setVisible] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const [form] = Form.useForm();
const handleOk = async () => {
try {
const values = await form.validateFields();
setConfirmLoading(true);
await saveData(values); // асинхронная функция сохранения
message.success('Форма успешно отправлена');
setVisible(false);
form.resetFields();
} catch (err) {
message.error('Ошибка при отправке формы');
} finally {
setConfirmLoading(false);
}
};
return (
<>
<Button onCl ick={() => setVisible(true)}>Открыть форму</Button>
<Modal
visible={visible}
title="Форма с асинхронной отправкой"
onOk={handleOk}
confirmLoading={confirmLoading}
onCan cel={() => setVisible(false)}
>
<Form form={form} layout="vertical">
<Form.Item
name="username"
label="Имя пользователя"
rules={[{ required: true, message: 'Введите имя пользователя' }]}
>
<Input />
</Form.Item>
</Form>
</Modal>
</>
);
};
Особенности подхода с Form:
validateFields).confirmLoading предотвращает повторные отправки при
долгой обработке.form.resetFields()) после успешной
операции гарантирует чистое состояние при следующем открытии модального
окна.message, notification или
Spin внутри модального окна.confirmLoading.Иногда стандартной кнопки OK недостаточно, и требуется реализовать кастомные кнопки с собственными асинхронными обработчиками:
<Modal
visible={visible}
title="Кастомные действия"
footer={[
<Button key="back" onCl ick={() => setVisible(false)}>
Отмена
</Button>,
<Button
key="submit"
type="primary"
loading={confirmLoading}
onCl ick={async () => {
setConfirmLoading(true);
await doAsyncTask();
setConfirmLoading(false);
setVisible(false);
}}
>
Сохранить
</Button>,
]}
>
<p>Модальное окно с кастомными кнопками и асинхронными действиями.</p>
</Modal>
Преимущества кастомного футера:
loading,
disabled).Асинхронные операции в модальных окнах Ant Design позволяют создавать
сложные интерактивные интерфейсы, обеспечивая корректное управление
состоянием, UX и обработкой ошибок. Комбинация
confirmLoading, ручного управления
видимостью и встроенных форм дает полное управление асинхронной логикой
внутри диалогов.