Bỏ qua để đến nội dung chính

Xử lý tệp

Dropup cung cấp trải nghiệm liền mạch để xử lý tệp từ lúc chúng được chọn cho đến khi được tải lên.

Các phương thức chọn tệp

Kéo và thả

Sử dụng getDropProps() để bật kéo-thả trên bất kỳ phần tử nào:

function DropZone() {
const { getDropProps, getInputProps, state } = useDropup();

return (
<div
{...getDropProps()}
style={{
border: state.isDragging ? '2px dashed blue' : '2px dashed gray',
backgroundColor: state.isDragging ? '#f0f8ff' : 'transparent',
}}
>
<input {...getInputProps()} />
<p>Thả tệp vào đây</p>
</div>
);
}

Nhấp để chọn

Vùng thả cũng có thể nhấp được theo mặc định:

<div {...getDropProps()}>
<input {...getInputProps()} />
<p>Nhấp hoặc kéo tệp vào đây</p>
</div>

Chọn theo chương trình

Mở hộp thoại tệp theo chương trình:

const { openFileDialog } = useDropup();

<button onClick={openFileDialog}>
Chọn tệp
</button>

Thêm tệp theo chương trình

Thêm tệp trực tiếp (hữu ích cho sự kiện paste hoặc tích hợp):

const { actions } = useDropup();

// Từ clipboard
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files?.length) {
actions.addFiles(files);
}
});

Cấu trúc đối tượng tệp

Mỗi tệp trong mảng files có cấu trúc này:

interface DropupFile {
// Định danh
id: string; // Mã định danh duy nhất (tự động tạo)
file: File; // Đối tượng File gốc của trình duyệt

// Metadata
name: string; // Tên tệp
size: number; // Kích thước tính bằng bytes
type: string; // Loại MIME (vd: "image/png")

// Xem trước (cho hình ảnh)
preview?: string; // Object URL để xem trước

// Trạng thái tải lên
status: FileStatus; // 'idle' | 'uploading' | 'complete' | 'error' | 'paused'
progress: number; // 0-100

// Kết quả
uploadedUrl?: string; // URL sau khi tải lên thành công
response?: unknown; // Phản hồi từ máy chủ
error?: DropupError; // Chi tiết lỗi nếu thất bại

// Dữ liệu tùy chỉnh
meta?: Record<string, unknown>;
}

Vòng đời trạng thái tệp

idle → uploading → complete
↘ error → (thử lại) → uploading
↘ paused → (tiếp tục) → uploading

Các giá trị trạng thái

Trạng tháiMô tả
idleTệp đã thêm nhưng chưa tải lên
uploadingĐang tải lên
completeTải lên thành công
errorTải lên thất bại
pausedTải lên tạm dừng (cho tải lên có thể tiếp tục)

Làm việc với tệp

Truy cập tệp

const { files } = useDropup();

// Tất cả tệp
console.log(files);

// Lọc theo trạng thái
const uploading = files.filter(f => f.status === 'uploading');
const completed = files.filter(f => f.status === 'complete');
const failed = files.filter(f => f.status === 'error');

Xóa tệp

const { files, actions } = useDropup();

// Xóa một tệp
actions.remove(files[0].id);

// Xóa tất cả tệp
actions.reset();

Cập nhật metadata tệp

const { actions } = useDropup();

// Thêm metadata tùy chỉnh
actions.updateFileMeta(fileId, {
customField: 'value',
category: 'documents',
});

Xem trước tệp

Đối với tệp hình ảnh, Dropup có thể tạo URL xem trước:

const { files } = useDropup({
generatePreviews: true, // mặc định: true
});

// Sử dụng xem trước trong UI của bạn
{files.map(file => (
file.preview && (
<img
src={file.preview}
alt={file.name}
style={{ maxWidth: 100, maxHeight: 100 }}
/>
)
))}
Quản lý bộ nhớ

URL xem trước là Object URLs tiêu tốn bộ nhớ. Dropup tự động thu hồi chúng khi tệp bị xóa hoặc component unmount.

Định dạng kích thước tệp

Hàm trợ giúp để hiển thị kích thước tệp:

function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// Sử dụng
{files.map(file => (
<span>{formatFileSize(file.size)}</span>
))}

Xử lý tệp lớn

Đối với tệp lớn, xem xét tải lên theo khối:

import { useDropup, createChunkedUploader } from '@samithahansaka/dropup';

const { files } = useDropup({
upload: createChunkedUploader({
url: '/api/upload',
chunkSize: 5 * 1024 * 1024, // Khối 5MB
}),
});

Xem Tải lên theo khối để biết thêm chi tiết.