Перейти к основному содержимому

Хуки загрузки файлов

Хуки useUploader и useDropzone предоставляют функционал для загрузки файлов с прогресс-баром и drag & drop интерфейсом.

useUploader()

Хук для загрузки файлов с отслеживанием прогресса.

Возвращаемые методы

  • upload() — загрузка файла
  • uploadProgress — прогресс загрузки (0-100)
  • isUploading — состояние загрузки
  • error — ошибка загрузки

Пример

import { useUploader } from '@emd-cloud/react-components';
import { useState } from 'react';

function FileUpload() {
const { upload, uploadProgress, isUploading } = useUploader();
const [fileUrl, setFileUrl] = useState('');

const handleFileChange = async (e) => {
const file = e.target.files[0];
if (!file) return;

try {
const result = await upload(file);
setFileUrl(result.url);
console.log('Файл загружен:', result.url);
} catch (error) {
console.error('Ошибка загрузки:', error);
}
};

return (
<div>
<input type="file" onChange={handleFileChange} disabled={isUploading} />

{isUploading && (
<div>
<progress value={uploadProgress} max="100" />
<span>{uploadProgress}%</span>
</div>
)}

{fileUrl && (
<div>
<p>Файл загружен!</p>
<a href={fileUrl} target="_blank" rel="noopener noreferrer">
Открыть файл
</a>
</div>
)}
</div>
);
}

useDropzone()

Хук для создания drag & drop зоны загрузки файлов.

Возвращаемые значения

  • getRootProps() — props для контейнера
  • getInputProps() — props для input элемента
  • isDragActive — состояние перетаскивания
  • acceptedFiles — принятые файлы
  • rejectedFiles — отклоненные файлы

Пример

import { useDropzone, useUploader } from '@emd-cloud/react-components';
import { useState } from 'react';

function DropzoneUpload() {
const { upload } = useUploader();
const [uploadedFiles, setUploadedFiles] = useState([]);

const { getRootProps, getInputProps, isDragActive } = useDropzone({
accept: {
'image/*': ['.png', '.jpg', '.jpeg', '.gif']
},
maxSize: 5 * 1024 * 1024, // 5 MB
onDrop: async (acceptedFiles) => {
for (const file of acceptedFiles) {
try {
const result = await upload(file);
setUploadedFiles(prev => [...prev, result]);
} catch (error) {
console.error('Ошибка загрузки:', error);
}
}
}
});

return (
<div>
<div
{...getRootProps()}
style={{
border: '2px dashed #ccc',
padding: '20px',
textAlign: 'center',
cursor: 'pointer',
backgroundColor: isDragActive ? '#e0e0e0' : 'white'
}}
>
<input {...getInputProps()} />
{isDragActive ? (
<p>Отпустите файлы здесь...</p>
) : (
<p>Перетащите файлы сюда или нажмите для выбора</p>
)}
</div>

{uploadedFiles.length > 0 && (
<div>
<h3>Загруженные файлы:</h3>
{uploadedFiles.map((file, index) => (
<div key={index}>
<a href={file.url} target="_blank" rel="noopener noreferrer">
Файл {index + 1}
</a>
</div>
))}
</div>
)}
</div>
);
}

Загрузка изображений с предпросмотром

function ImageUpload() {
const { upload, uploadProgress, isUploading } = useUploader();
const [preview, setPreview] = useState('');
const [uploadedUrl, setUploadedUrl] = useState('');

const handleFileSelect = async (e) => {
const file = e.target.files[0];
if (!file) return;

// Создаем предпросмотр
const reader = new FileReader();
reader.onload = (e) => setPreview(e.target.result);
reader.readAsDataURL(file);

// Загружаем файл
try {
const result = await upload(file);
setUploadedUrl(result.url);
} catch (error) {
console.error('Ошибка:', error);
}
};

return (
<div>
<input
type="file"
accept="image/*"
onChange={handleFileSelect}
disabled={isUploading}
/>

{preview && (
<div>
<img src={uploadedUrl || preview} alt="Preview" style={{ maxWidth: '300px' }} />
{isUploading && <p>Загрузка: {uploadProgress}%</p>}
</div>
)}
</div>
);
}

Следующие шаги

Полезные ссылки