#reactjs #react-dnd
#reactjs #react-dnd
Вопрос:
Я хочу создать функцию загрузки файлов в react с использованием React dnd, где пользователь должен иметь возможность загружать файлы, помещая их в div
Ответ №1:
Привет, я предлагаю это решение —
<div
className="file-select"
onDragOver={dragOver}
onDragEnter={dragEnter}
onDragLeave={dragLeave}
onDrop={fileDrop}
onClick={fileInputClicked}
>
<h4>Select File</h4>
<input
ref={fileInputRef}
className="file-input"
type="file"
multiple
onChange={filesSelected}
/>
</div>
также предлагаю использовать ref:
const fileInputRef = useRef();
Это только скелет — вам нужно реализовать эти методы —
учитывать проверку — какие файлы поддерживаются и т.д.
Кроме того, вы можете реализовать предварительный просмотр файлов, удаление и т. Д. — Поэтому в этом случае важен дизайн или, по крайней мере, концепция решения
Например, я использую эту функцию для множественного выбора:
const [selectedFiles, setSelectedFiles] = useState([]);
const [validFiles, setValidFiles] = useState([]);
const [unsupportedFiles, setUnsupportedFiles] = useState([]);
const filesSelected = () => {
if (fileInputRef.current.files.length) {
handleFiles(fileInputRef.current.files);
}
};
const handleFiles = (files) => {
for (let i = 0; i < files.length; i ) {
if (validateFile(files[i])) {
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
} else {
files[i].invalid = true;
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
setErrorMessage('File type not permitted');
setUnsupportedFiles((prevArray) => [...prevArray, files[i]]);
}
}
handleFileData(files);
};
Ответ №2:
Для этой цели вы можете использовать пакет react dropzone.
npm install --save react-dropzone
или:
yarn add react-dropzone
Пример фрагмента с использованием перехватов
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
Пример фрагмента с использованием компонента-оболочки
import React from 'react'
import Dropzone from 'react-dropzone'
<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
Используя обратный вызов onDrop, вы можете получить массив acceptedFiles, содержащий файлы. Вы также можете ограничить размер, разрешить несколько или только один и тип файлов, которые вы хотите принять.
Ниже приведен пример фрагмента, в котором разрешено несколько изображений размером 10 МБ, и разрешены только расширения png, jpg, jpeg.
<Dropzone
multiple={true}
minSize={0}
maxSize={10485760}
accept="image/png,image/jpg,image/jpeg"
onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
Ответ №3:
проверьте react-uploady — upload-drop-zone
Вы можете начать с очень небольшого кода, например:
import Uploady from "@rpldy/uploady";
import UploadDropZone from "@rpldy/upload-drop-zone";
const App = () => (
<Uploady destination={{url: "https://my-server.com/upload"}}>
<UploadDropZone onDragOverClassName="drag-over">
<span>Dragamp;Drop File(s) Here</span>
</UploadDropZone>
</Uploady>);