Drag-n-drop загрузчик файлов в React
Development, Java | Комментировать запись
react-dropzone – это совместимый с HTML5 компонент React для обработки перетаскивания файлов.
HTML5 поддерживает загрузку файлов через <input type=”file” />. Компонент react-dropzone предоставляет дополнительные функции, среди которых настройка области перетаскивания, предварительный просмотр и ограничение типа и количества файлов.
В этом руководстве вы узнаете, как добавить response-dropzone в свой проект React, и изучите некоторые из предоставляемых им базовых функций.
Требования
Для выполнения этого урока вам понадобится локальная установка Node.js. Следуйте инструкциям для вашего дистрибутива: mac OS, Ubuntu, Debian, CentOS.
Руководство было проверено на версиях Node v15.3.0, npm v7.4.0, react v17.0.1 и react-dropzone v11.2.4.
1: Создание тестового проекта
Начнем с создания простого проекта. С помощью create-react-app сгенерируйте приложение React.
npx create-react-app react-dropzone-example
Перейдите в новый каталог:
cd react-dropzone-example
Установите react-dropzone:
npm install react-dropzone@11.2.4
Теперь у вас есть новый проект React с компонентом react-dropzone.
2: Добавление компонента Dropzone
У response-dropzone есть стандартные настройки, которые позволяют добавлять его в приложения при помощи минимальной конфигурации.
Как минимум, вам понадобится свойство onDrop, которое будет обрабатывать перетаскиваемые в область файлы и базовый текст с призывом к действию, чтобы помочь пользователю разобраться. В файл src/DropzoneComponent.js добавьте:
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
function DropzoneComponent() {
const onDrop = useCallback(acceptedFiles => {
console.log(acceptedFiles);
}, []);
const {
getRootProps,
getInputProps
} = useDropzone({
onDrop
});
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<div>Drag and drop your images here.</div>
</div>
)
}
export default DropzoneComponent;
Этот код обеспечивает обработку перетаскивания файлов в вашем приложении.
Примечание: Стоит отметить, что, хотя зона response-dropzone и предназначена для перетаскивания файлов, по умолчанию она принимает события клика, которые запускают диалоговое окно для выбора файлов.
Добавьте этот компонент в свое приложение React (файл src/App.js):
import DropzoneComponent from './DropzoneComponent'; function App() { return ( <div className="App"> <DropzoneComponent /> </div> ); } export default App;
Запустите приложение и понаблюдайте за ним в веб-браузере. Вы должны увидеть элемент div с текстом:
Drag and drop your images here
Попробуйте перетащить разные файлы в компонент Dropzone. В настоящее время для отображения файлов код использует console.log. Информация из загруженных файлов включает имя, дату последнего изменения, размер и тип (name, lastModified, size, and type).
На данный момент у нас есть рабочий компонент React Dropzone с конфигурацией по умолчанию. Дополнительные параметры конфигурации можно найти в документации response-dropzone.
3: Стилизация компонента Dropzone
По умолчанию зона сброса response-dropzone не оформлена. В документации представлены стили для общего оформления этой зоны, где используется комбинация гибкого блока и пунктирных границ, которая указывает пользователям на область для перетаскивания файлов.
Также response-dropzone поддерживает свойства для ситуаций, когда с компонентом активно взаимодействуют (isDragActive), компонент принимает (isDragAccept) или отклоняет файл (isDragReject).
Пересмотрите свой DropzoneComponent и добавьте isDragActive, isDragAccept и isDragReject, которые будут применяться к типам файлов JPEG и PNG:
import React, { useCallback, useMemo } from 'react'; import { useDropzone } from 'react-dropzone'; const baseStyle = { display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '20px', borderWidth: 2, borderRadius: 2, borderColor: '#eeeeee', borderStyle: 'dashed', backgroundColor: '#fafafa', color: '#bdbdbd', transition: 'border .3s ease-in-out' }; const activeStyle = { borderColor: '#2196f3' }; const acceptStyle = { borderColor: '#00e676' }; const rejectStyle = { borderColor: '#ff1744' }; function DropzoneComponent(props) { const onDrop = useCallback(acceptedFiles => { console.log(acceptedFiles); }, []); const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({ onDrop, accept: 'image/jpeg, image/png' }); const style = useMemo(() => ({ ...baseStyle, ...(isDragActive ? activeStyle : {}), ...(isDragAccept ? acceptStyle : {}), ...(isDragReject ? rejectStyle : {}) }), [ isDragActive, isDragReject, isDragAccept ]); return ( <div {...getRootProps({style})}> <input {...getInputProps()} /> <div>Drag and drop your images here.</div> </div> ) } export default DropzoneComponent;
В результате у вас будет стандартная зона для перетаскивания файлов, отмеченная пунктирной линией по периметру.
Зона сброса с поддержкой свойств isDragActive, isDragAccept и isDragReject предоставит пользователю обратную связь о том, действителен ли его файл.
4: Добавление превью изображений
Предварительный просмотр – это копия изображения, которое перетаскивается в зону сброса. Благодаря этому пользователи получают визуальную обратную связь и могут сразу проверить, правильные ли изображения они добавили.
Предварительный просмотр был удален в версии 7.0.0, однако документация предоставляет альтернативный способ добавить предпросмотр – с помощью комбинации Object.assign() и URL.createObjectURL().
Вернитесь к своему компоненту src/DropzoneComponent.js и добавьте предварительный просмотр:
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDropzone } from 'react-dropzone'; const baseStyle = { display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '20px', borderWidth: 2, borderRadius: 2, borderColor: '#eeeeee', borderStyle: 'dashed', backgroundColor: '#fafafa', color: '#bdbdbd', transition: 'border .3s ease-in-out' }; const activeStyle = { borderColor: '#2196f3' }; const acceptStyle = { borderColor: '#00e676' }; const rejectStyle = { borderColor: '#ff1744' }; function DropzoneComponent(props) { const [files, setFiles] = useState([]); const onDrop = useCallback(acceptedFiles => { setFiles(acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }))); }, []); const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({ onDrop, accept: 'image/jpeg, image/png' }); const style = useMemo(() => ({ ...baseStyle, ...(isDragActive ? activeStyle : {}), ...(isDragAccept ? acceptStyle : {}), ...(isDragReject ? rejectStyle : {}) }), [ isDragActive, isDragReject, isDragAccept ]); const thumbs = files.map(file => ( <div key={file.name}> <img src={file.preview} alt={file.name} /> </div> )); // clean up useEffect(() => () => { files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files]); return ( <section> <div {...getRootProps({style})}> <input {...getInputProps()} /> <div>Drag and drop your images here.</div> </div> <aside> {thumbs} </aside> </section> ) } export default DropzoneComponent;
Примечание: Чтобы избежать сохранения ненужных предварительных просмотров, нужно вызвать URL.revokeObjectURL(file.preview).
Теперь всякий раз, когда пользователь перетаскивает файл (или файлы) в зону сброса, на экране будет отображаться предварительный просмотр.
Заключение
В этом руководстве вы познакомились с функцией response-dropzone и узнали о том, как ее можно использовать в приложении React для расширения функций перетаскивания файлов.
Tags: React