檔案處理
Dropup 提供從檔案被選擇到上傳完成的無縫體驗。
檔案選擇方法
拖放
使用 getDropProps() 在任何元素上啟用拖放功能:
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>將檔案拖放到此處</p>
</div>
);
}
點擊選擇
拖放區域預設也可以點擊:
<div {...getDropProps()}>
<input {...getInputProps()} />
<p>點擊或拖放檔案到此處</p>
</div>
程式化選擇
以程式化方式開啟檔案對話框:
const { openFileDialog } = useDropup();
<button onClick={openFileDialog}>
選擇檔案
</button>
程式化新增檔案
直接新增檔案(適用於貼上事件或整合):
const { actions } = useDropup();
// 從剪貼簿
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files?.length) {
actions.addFiles(files);
}
});
檔案物件結構
files 陣列中的每個檔案具有以下結構:
interface DropupFile {
// 識別
id: string; // 唯一識別碼(自動產生)
file: File; // 原始瀏覽器 File 物件
// 元資料
name: string; // 檔案名稱
size: number; // 大小(位元組)
type: string; // MIME 類型(例如 "image/png")
// 預覽(圖片用)
preview?: string; // 預覽用的 Object URL
// 上傳狀態
status: FileStatus; // 'idle' | 'uploading' | 'complete' | 'error' | 'paused'
progress: number; // 0-100
// 結果
uploadedUrl?: string; // 上傳成功後的 URL
response?: unknown; // 伺服器回應
error?: DropupError; // 失敗時的錯誤詳情
// 自訂資料
meta?: Record<string, unknown>;
}
檔案狀態生命週期
idle → uploading → complete
↘ error → (retry) → uploading
↘ paused → (resume) → uploading
狀態值
| 狀態 | 描述 |
|---|---|
idle | 檔案已新增但尚未上傳 |
uploading | 正在上傳 |
complete | 上傳成功 |
error | 上傳失敗 |
paused | 上傳已暫停(用於可恢復上傳) |
處理檔案
存取檔案
const { files } = useDropup();
// 所有檔案
console.log(files);
// 按狀態篩選
const uploading = files.filter(f => f.status === 'uploading');
const completed = files.filter(f => f.status === 'complete');
const failed = files.filter(f => f.status === 'error');
移除檔案
const { files, actions } = useDropup();
// 移除單一檔案
actions.remove(files[0].id);
// 移除所有檔案
actions.reset();
更新檔案元資料
const { actions } = useDropup();
// 新增自訂元資料
actions.updateFileMeta(fileId, {
customField: 'value',
category: 'documents',
});
檔案預覽
對於圖片檔案,Dropup 可以產生預覽 URL:
const { files } = useDropup({
generatePreviews: true, // 預設:true
});
// 在您的 UI 中使用預覽
{files.map(file => (
file.preview && (
<img
src={file.preview}
alt={file.name}
style={{ maxWidth: 100, maxHeight: 100 }}
/>
)
))}
記憶體管理
預覽 URL 是會消耗記憶體的 Object URL。當檔案被移除或元件卸載時,Dropup 會自動釋放它們。
檔案大小格式化
顯示檔案大小的輔助函式:
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];
}
// 用法
{files.map(file => (
<span>{formatFileSize(file.size)}</span>
))}
處理大檔案
對於大檔案,請考慮分塊上傳:
import { useDropup, createChunkedUploader } from '@samithahansaka/dropup';
const { files } = useDropup({
upload: createChunkedUploader({
url: '/api/upload',
chunkSize: 5 * 1024 * 1024, // 5MB 區塊
}),
});
更多詳情請參閱分塊上傳。