메인 콘텐츠로 건너뛰기

Dropup 작동 방식

Dropup은 헤드리스 UI 개념을 기반으로 구축되었습니다 - 모든 복잡한 파일 업로드 로직을 처리하면서 시각적 프레젠테이션에 대한 완전한 제어권을 제공합니다.

아키텍처

┌─────────────────────────────────────────────────────────────┐
│ React 컴포넌트 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 드롭 영역 │ │ 파일 목록 │ │ 업로드 버튼 │ │
│ │ (사용자 UI) │ │ (사용자 UI) │ │ (사용자 UI) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ useDropup 훅 ││
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────┐ ││
│ │ │유효성 검사 │ │ 상태 │ │ 업로드 │ │ 플랫폼 │ ││
│ │ │ 엔진 │ │ 관리자 │ │ 엔진 │ │ 어댑터 │ ││
│ │ └───────────┘ └───────────┘ └───────────┘ └─────────┘ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

핵심 컴포넌트

1. 상태 관리자

Dropup은 예측 가능한 상태 관리를 위해 React의 useReducer를 사용합니다:

  • 모든 파일과 상태 추적
  • 드래그 상태 관리
  • 업로드 진행률 처리
  • 계산된 값 제공

2. 유효성 검사 엔진

파일이 추가되기 전에 유효성 검사를 거칩니다:

const { files } = useDropup({
accept: 'image/*', // 파일 타입 유효성 검사
maxSize: 5 * 1024 * 1024, // 최대 파일 크기
minSize: 1024, // 최소 파일 크기
maxFiles: 10, // 최대 파일 수
maxWidth: 4096, // 최대 이미지 너비
maxHeight: 4096, // 최대 이미지 높이
customRules: [ // 커스텀 유효성 검사
(file) => file.name.length < 100 || '파일 이름이 너무 깁니다'
],
});

3. 업로드 엔진

업로드 엔진은 다음을 처리합니다:

  • 단순 업로드 (파일당 단일 요청)
  • 청크 업로드 (대용량 파일 분할)
  • 지수 백오프를 사용한 재시도 로직
  • 동시 업로드 관리
  • 진행률 추적

4. 플랫폼 어댑터

Dropup은 여러 플랫폼에서 작동합니다:

  • - 네이티브 브라우저 API 사용
  • React Native - 네이티브 파일 처리 사용
  • SSR - 서버 사이드 렌더링에 안전

데이터 흐름

사용자 액션 → 유효성 검사 → 상태 업데이트 → 업로드 → 콜백
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
파일 선택/ 수락/거부 files[] XHR/Fetch onComplete
드롭 업데이트 진행률 onError

설계 원칙

1. 헤드리스 우선

내장 UI 컴포넌트 없음 - 필요한 것을 정확히 구축합니다:

// UI 전체를 제어합니다
<div {...getDropProps()}>
<YourCustomDropZone />
<input {...getInputProps()} />
</div>

2. 타입 안전성

포괄적인 타입을 갖춘 완전한 TypeScript 지원:

import type { DropupFile, UseDropupOptions } from '@samithahansaka/dropup';

const options: UseDropupOptions = {
accept: 'image/*',
onUploadComplete: (file: DropupFile) => {
console.log(file.uploadedUrl);
},
};

3. 트리 쉐이킹 가능

필요한 것만 가져오기:

// 코어만 (~10KB)
import { useDropup } from '@samithahansaka/dropup';

// 필요할 때 클라우드 지원 추가
import { createS3Uploader } from '@samithahansaka/dropup/cloud/s3';

// 필요할 때 이미지 처리 추가
import { compressImage } from '@samithahansaka/dropup/image';

4. 점진적 향상

간단하게 시작하고 필요에 따라 기능 추가:

// 기본 사용법
const { files } = useDropup();

// 유효성 검사 추가
const { files } = useDropup({ maxSize: 10_000_000 });

// 자동 업로드 추가
const { files } = useDropup({
maxSize: 10_000_000,
upload: { url: '/api/upload' },
autoUpload: true,
});

// 클라우드 스토리지 추가
const { files } = useDropup({
upload: createS3Uploader({ getPresignedUrl }),
});