Upload

Компонент Upload предназначен для реализации интерфейса загрузки файлов на сервер. Он поддерживает множество сценариев, включая одиночную и множественную загрузку, предварительный просмотр файлов, кастомизацию кнопок и контроль над процессом загрузки.


Базовое использование

Простейший пример загрузки файла выглядит следующим образом:

import { Upload, Button } from 'antd';
import { UploadOutlined } from '@ant-design/icons';

const props = {
  action: '/upload.do', // URL для отправки файла
};

<Upload {...props}>
  <Button icon={<UploadOutlined />}>Загрузить файл</Button>
</Upload>

Ключевые свойства:

  • action — URL, на который отправляется файл.
  • beforeUpload — функция, выполняющаяся перед загрузкой. Позволяет проверять файл и отменять загрузку.
  • onChange — обработчик событий изменения состояния загрузки (uploading, done, error, removed).
  • multiple — разрешает загрузку нескольких файлов одновременно.
  • accept — ограничивает типы файлов для выбора (.png, .jpg, .pdf).

Контроль состояния файлов

Компонент Upload предоставляет объект fileList, который позволяет управлять списком файлов программно:

import { Upload, Button } from 'antd';
import { useState } from 'react';
import { UploadOutlined } from '@ant-design/icons';

const ControlledUpload = () => {
  const [fileList, setFileList] = useState([]);

  const handleChange = ({ fileList: newFileList }) => {
    setFileList(newFileList);
  };

  return (
    <Upload
      action="/upload.do"
      fileList={fileList}
      onCha nge={handleChange}
    >
      <Button icon={<UploadOutlined />}>Загрузить файл</Button>
    </Upload>
  );
};

Использование контролируемого fileList позволяет реализовать кастомную логику обработки файлов, фильтрацию, удаление или сортировку.


Ограничение размеров и типов файлов

beforeUpload позволяет проверять файл перед отправкой:

const beforeUpload = (file) => {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('Можно загружать только JPG/PNG файлы!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('Файл должен быть меньше 2MB!');
  }
  return isJpgOrPng && isLt2M;
};

<Upload
  action="/upload.do"
  beforeUpload={beforeUpload}
>
  <Button icon={<UploadOutlined />}>Загрузить файл</Button>
</Upload>

Преимущества beforeUpload:

  • Проверка формата файлов
  • Ограничение размера
  • Возможность отмены загрузки

Пользовательский рендер кнопки

Компонент Upload поддерживает кастомные элементы управления:

<Upload
  action="/upload.do"
  listType="picture-card"
>
  {fileList.length >= 3 ? null : <div>Добавить фото</div>}
</Upload>

Параметр listType позволяет изменить отображение списка файлов:

  • text — стандартный текстовый список
  • picture — список с миниатюрами
  • picture-card — карточки для изображений с кнопкой добавления

Загрузка нескольких файлов

Для загрузки сразу нескольких файлов используется свойство multiple:

<Upload
  action="/upload.do"
  multiple
>
  <Button icon={<UploadOutlined />}>Загрузить несколько файлов</Button>
</Upload>

Файлы добавляются в один fileList, где каждый элемент содержит статус (uploading, done, error) и информацию о файле (name, size, uid).


Предварительный просмотр файлов

Для изображений можно использовать функцию onPreview:

const handlePreview = async (file) => {
  let src = file.url;
  if (!src) {
    src = await new Promise((resolve) => {
      const reader = new FileReader();
      reader.readAsDataURL(file.originFileObj);
      reader.onl oad = () => resolve(reader.result);
    });
  }
  const imgWindow = window.open(src);
  imgWindow?.document.write(`<img src="${src}" />`);
};

<Upload
  action="/upload.do"
  listType="picture-card"
  onPrev iew={handlePreview}
>
</Upload>

Это позволяет отображать изображения в отдельном окне без отправки на сервер.


Кастомная загрузка файлов

Вместо автоматической отправки файлов можно использовать customRequest:

const customUpload = ({ file, onSuccess, onError }) => {
  const formData = new FormData();
  formData.append('file', file);
  fetch('/upload.do', {
    method: 'POST',
    body: formData,
  })
    .then(() => onSuccess("ok"))
    .catch(onError);
};

<Upload
  customRequest={customUpload}
>
  <Button icon={<UploadOutlined />}>Загрузить файл</Button>
</Upload>

Преимущества customRequest:

  • Полный контроль над процессом
  • Возможность интеграции с любой API
  • Поддержка прогресс-бара и уведомлений

Прогресс загрузки

Компонент автоматически отображает прогресс загрузки. Для дополнительного контроля используется onChange:

const handleChange = (info) => {
  if (info.file.status === 'uploading') {
    console.log(`Загрузка: ${info.file.percent.toFixed(2)}%`);
  }
};

info.file.percent возвращает процент завершения загрузки, что позволяет создавать кастомные индикаторы.


Удаление и управление списком файлов

Файлы можно удалять через интерфейс или программно:

const handleRemove = (file) => {
  console.log('Удаление файла:', file.name);
  return true; // Возвращение true подтверждает удаление
};

<Upload
  action="/upload.do"
  onRem ove={handleRemove}
>
</Upload>

onRemove позволяет блокировать удаление или выполнять дополнительную логику на сервере.


Интеграция с Form

Upload полностью совместим с Form.Item:

import { Form } from 'antd';

<Form.Item
  name="upload"
  valuePropName="fileList"
  getValueFromEvent={({ fileList }) => fileList}
  rules={[{ required: true, message: 'Файл обязателен' }]}
>
  <Upload action="/upload.do" listType="picture">
    <Button icon={<UploadOutlined />}>Загрузить файл</Button>
  </Upload>
</Form.Item>

Использование valuePropName="fileList" и getValueFromEvent обеспечивает корректное взаимодействие с формой.


Рекомендации по использованию

  • Для изображений рекомендуется listType="picture-card" с onPreview.
  • Для больших файлов использовать customRequest для контроля прогресса.
  • Всегда проверять файлы через beforeUpload для предотвращения некорректной загрузки.
  • Для множества файлов использовать multiple и управляемый fileList.
  • Интегрировать с Form.Item для валидации и отправки вместе с другими данными формы.

Эти возможности делают компонент Upload гибким инструментом для реализации любых сценариев загрузки файлов в приложениях на React с использованием Ant Design.