В недавнем проекте мне пришлось создать компонент формы для приложения React и один из элементов формы, необходимых для того, чтобы пользователь мог загрузить файл. Компонент Выгрузка Ant Design делает этот процесс чрезвычайно простым, поскольку в него встроено большинство необходимых вам функций управления файлами внешнего интерфейса.

Upload не зависит от Form компонента Ant Design. Вы можете использовать его в модальных окнах или просто отдельно. В моем случае коллега сообщил мне, что компонент Form может быть лучше, чем модальный с входами, потому что мне придется меньше полагаться на локальное состояние. Я должен сказать, что компонент Form довольно надежен.

Я подробнее расскажу, как я использовал Компонент формы, но, хотя компонент Form надежен, все, что вам нужно для работы компонента Upload в вашем приложении React, - это установить зависимость дизайна муравья и импортировать Upload от него. После установки зависимости включите эти две строки в верхней части вашего компонента:

import "antd/dist/antd.css";
import {Upload} from "antd";

Если вы планируете загружать стили с помощью Webpack, ознакомьтесь с этим вопросом и ответом на StackOverflow. Для получения дополнительной информации о начале работы с Ant Design нажмите здесь. Как только все будет импортировано, мы можем начать его использовать.

Компонент Form.Item позволяет нам использовать props, предоставленный компонентом Form, чтобы лучше обрабатывать ввод формы. Один из предоставляемых им реквизитов - getFieldDecorator.

getFieldDecorator допускает двустороннюю привязку для нашей формы. Это позволяет нам управлять вводом без использования локального состояния. Обернув наш Upload компонент в getFieldDecorator, , мы можем передавать параметры нашему вводу для улучшения обработки формы. Как вы можете видеть на изображении выше, мы используем его для передачи параметра initialValue (синоним значения по умолчанию), а также параметра valuePropName (используется для различения данных в элементах формы). Последний параметр, который я передаю getFieldDecorator , - getValueFromEvent.

Это параметр, который принимает аргумент как функцию, которую можно использовать для анализа данных в событии, которое запускается, когда пользователь загружает файл. Мы будем использовать его, чтобы определять, какая информация передается нашему Upload компоненту, и манипулировать ею в соответствии с нашими потребностями (например, ограничивая количество файлов, которые могут быть загружены за один раз). Есть и другие параметры, которые вы можете использовать в getFieldDecorator, такие как правила (например, создание требуемого ввода, добавление сообщения, если ввод не был заполнен, назначение приемлемого типа данных и т. Д.), А также другие валидаторы ввода формы и пользовательские функции.

Теперь вернемся к компоненту Upload.

Компонент Upload имеет свойства, аналогичные свойствам элемента ввода HTML с типом «файл», например name и accept. В моем случае принимаются только zip-файлы.

В Upload компоненте обычно требуется действие. Действие включает URL-адрес загрузки, позволяющий нам увидеть, куда будет отправлен ваш файл. Поскольку я передаю файл вместе с другими данными в форме в конкретную конечную точку в нашей базе данных, действие не требуется. Чтобы обойти требование к действию, я внедряю customRequest.

Эта функция ничего не делает.

Шутки в сторону. Это просто заполнитель действия, поэтому я не получаю сообщение об ошибке при загрузке. Это мой customRequest, метко названный dummyRequest.

Вот и все. Его задача - просто обмануть Upload компонент, заставив думать, что действие включено. customRequest можно использовать не только для обмана Upload компонентов, но в нашем случае этот обман - единственное, что нам нужно от него.

Теперь данные нашего файла могут быть переданы в Form, не вызывая ошибки действия.

Помните нашу getValueFromEvent опору и функцию, которую мы ей передали? Здесь мы можем видеть не только fileList (массив выбранных файловых объектов), но и данные текущего выбранного файла. Вот как это выглядит, когда мы регистрируем это на нашей консоли:

Как видите, первое значение - это объект - файл, который загружается в данный момент. Этот объект содержит несколько атрибутов.

Первый атрибут, который мы рассмотрим, - это originalFileObj, который представляет собой фактический объект файла, содержащий данные файла. Некоторые атрибуты в этом объекте довольно просты, например файл name, файл type, size (представлен в байтах), а также информация о модификации. Другие, менее очевидные атрибуты, uid и webkitRelativePath, сейчас не будут нас сильно беспокоить. Но если вам интересно, загляните в раздел Файл веб-документации MDN.

Некоторые другие атрибуты в первом значении нашего объекта события также находятся в originalFileObj, но вот некоторые из них:

Процент: процент завершения загрузки.

Статус. Независимо от того, загружается файл или нет.

Ответ: ответ, который мы получаем на запрос загрузки.

Ошибка: если во время загрузки произошла ошибка.

Другой способ увидеть данные файла - использовать свойство beforeUpload. Это свойство - функция-перехватчик, которая выполняется перед загрузкой файла. Это хорошо, если вы планируете использовать состояние компонента, а не привязку данных формы. Вот пример функции beforeUpload:

Если вы зарегистрируете эти данные, вы увидите следующее:

Этот объект аналогичен первому значению в событии загрузки, захваченном нашей функцией normFile , но не включает статус, ответ, ошибку или процент. Это атрибуты, найденные в событии.

Помните: событие обычно содержит больше информации, чем входные данные, захваченные событием. Чтобы представить это в перспективе, чтобы получить результат ввода буквы в поле ввода текста HTML, вам нужно будет использовать event.target.value. Это связано с тем, что само событие содержит гораздо больше, чем просто входные данные. Подробнее об интерфейсе мероприятия вы можете узнать здесь.

Ты все еще со мной?

Теперь вернемся к нашему объекту события в normFile.

Второе значение в нашем объекте события - fileList. Этот объект содержит массив файловых объектов. Эти файловые объекты представляют файлы, которые были загружены и принадлежат компоненту Upload. fileList - это имя свойства, используемое компонентом Upload для различения данных.

Все это данные, фиксируемые в событии (изменении) при выборе файла для данных формы. Хотя здесь он не используется, вы также можете использовать onChange обработчик событий с компонентом Upload.

Функция normFile выполняет еще одну важную функцию, помимо возможности проверять данные, обнаруженные в событии загрузки. См. ниже.

Вся цель загрузки файла состоит в том, чтобы пользователь мог загрузить файл, содержащий данные, относящиеся к экземпляру объекта, создаваемому отправкой Form. Это позволяет пользователю создавать экземпляр объекта с начальными данными, а не создавать объект с пустыми атрибутами, только чтобы позже добавить данные из файла вручную. В зависимости от объема данных невозможно сказать, сколько времени это может сэкономить.

При чем здесь normFile? Что ж, если набор данных предназначен для моделирования на основе данных из одного источника, разрешение пользователю загружать более одного файла за раз может привести к объединению, дублированию или просто неверным данным. Представьте, что вы пытаетесь упростить себе жизнь, загружая файл вместо того, чтобы полагаться на ввод данных, но вы случайно (или намеренно) в конечном итоге выбираете больше, чем файл, который вам нужен. Теперь вы застряли с бесполезным чудовищем из беспорядочных файлов.

Хорошо, я драматичен. На самом деле это может быть обработано конечной точкой, просто отбросив общую ошибку или некоторую ошибку аргумента, если список файлов слишком длинный. Существуют также подлинные варианты использования для одновременной загрузки нескольких файлов (например, вложения электронной почты, сообщения в Instagram с несколькими изображениями и т. Д.). Но в моем случае это просто привело бы к конфликтам, поэтому с этим нужно бороться.

Чтобы решить эту проблему, мы могли бы использовать обработку ошибок из конечной точки и предоставить пользователю возможность повторно загрузить правильный файл. Или мы можем ограничить длину списка файлов одним файлом перед отправкой данных. Он работает так же, как и ввод. Таким образом, если данные необходимы или должны соответствовать определенному требованию, их можно обработать заранее, вместо того, чтобы конечная точка выдавала ошибку «Эй, пустышка, тебе нужно сделать это ...».

В функции normFile мы можем проверить длину fileList, и если она больше единицы, мы можем просто выполнить fileList.shift(), чтобы удалить элемент по первому индексу. Вы также можете просто написать fileList[1], чтобы получить только последний загруженный файл. Почему мы хотим опустить файл по первому индексу? Что ж, давайте посмотрим на fileList после попытки загрузить второй файл.

Как видите, у нас есть два объекта. Но посмотрите на статусы и ответы для каждого из них. Объект с первым индексом fileList имеет статус «готово» и ответ «ок». Второй объект имеет статус «загрузка», и ответ не определен. Что это говорит нам?

Объект с первым индексом - это предыдущий файл. Он уже загружается (отсюда и статус «выполнено»), и на самом деле есть ответ (то есть, запрос был разрешен и был возвращен ответ, подтверждающий это). Наш второй объект буквально говорит, что он все еще «загружается», что означает, что он в процессе. А ответ? Ну нет. Потому что запрос в процессе.

В зависимости от ваших предпочтений вы можете удалить последний добавленный файл и по умолчанию использовать предыдущий. Но для этого потребуется какое-то уведомление, чтобы пользователь знал: «Эй, вы пытались загрузить файл, но вы не можете загрузить больше одного, поэтому по умолчанию мы выбрали предыдущий». Но что, если пользователь знает, что он загрузил неправильный файл, и хочет просто повторно загрузить новый? Они могли удалить предыдущий загруженный файл. Или мы могли бы сделать это немного проще. Когда они загружают новый файл, он просто перезаписывает старый. Это то, что я решил здесь сделать, поэтому я удаляю файловый объект по первому индексу (сдвигу) массива.

Теперь вы можете эффективно и эффективно обрабатывать загрузку файлов. После захвата файлового объекта вы можете отправить эту информацию туда, где вы храните свои данные.

Обновите бесплатную подписку на Medium до платной здесь, и всего за 5 долларов в месяц вы получите неограниченное количество рассказов без рекламы от тысяч авторов из самых разных публикаций. Это партнерская ссылка, и часть вашего членства помогает мне получать вознаграждение за контент, который я создаю. Спасибо!

использованная литература