파일 처리
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 → (재시도) → uploading
↘ paused → (재개) → 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 청크
}),
});
자세한 내용은 청크 업로드를 참조하세요.