React와 Next.js로 간편하게 구현하는 드래그 앤 드롭 파일 업로더
2024-11-18 20:13:43webdevreactnextjstailwindcss
React와 Next.js로 구현하는 드래그 앤 드롭 파일 업로더
드래그 앤 드롭 파일 업로드 기능은 현대 웹 애플리케이션에서 사용자 경험을 높이는 중요한 요소입니다. 특히, React와 Next.js를 활용하면 더욱 효율적이고 강력하게 이 기능을 구현할 수 있습니다. 본 글에서는 드래그 앤 드롭 파일 업로더를 설계하고 구현하는 방법을 단계별로 설명하도록 하겠습니다.
주요 특징
- 드래그 앤 드롭 지원: 사용자가 파일을 업로드 구역으로 끌어와 놓으면 업로드가 가능합니다.
- 커스터마이즈 가능한 파일 형식 허용 설정: 허용되는 파일 형식을 지정할 수 있으며, 단일 또는 다중 파일 업로드를 지원할지 여부를 설정할 수 있습니다.
- 에러 처리: 잘못된 파일 형식 또는 파일 제한을 초과할 경우 적절한 에러 메시지를 표시합니다.
컴포넌트 속성
onFileSelect: 파일 선택 시 호출되는 콜백 함수.multiple: 다중 파일 업로드를 허용할지 여부를 결정하는 불리언 값(기본값: false).accept: 허용할 파일 형식을 지정하는 문자열(예: image/*).className: 업로드 영역의 스타일을 정의하기 위한 선택적 클래스.
상태 관리
컴포넌트는 두 가지 주요 상태를 가집니다:
dragActive: 파일이 업로드 구역에 드래그 중인지 여부를 추적하기 위한 불리언 값.error: 잘못된 파일 형식 또는 파일 수 초과 시 표시할 에러 메시지.
const [dragActive, setDragActive] = useState(false);
const [error, setError] = useState<string | null>(null);
드래그 이벤트 처리
파일 업로드 구역에 드래그 앤 드롭 기능을 구현하기 위해 다음의 드래그 이벤트를 수신합니다:
onDragEnter및onDragOver: 파일이 업로드 구역으로 드래그될 때 감지.onDragLeave: 드래그 영역에서 파일이 벗어나면 상태를 초기화.onDrop: 파일 드롭과 유효성 검사를 처리.
handleDrag 함수는 이벤트 유형에 따라 dragActive 상태를 토글하여 컴포넌트의 시각적 상태를 업데이트합니다.
const handleDrag = (e: React.DragEvent) => {
e.preventDefault();
e.stopPropagation();
setDragActive(e.type === "dragenter" || e.type === "dragover");
};
파일 드롭 유효성 검사
파일이 드롭되면 handleDrop 함수에서 여러 유효성을 검사합니다:
- 다중 파일 검사:
multiple값이 false일 경우 단일 파일만 업로드가 가능합니다. - 파일 형식 유효성 검사:
accept속성을 사용해 드롭된 파일이 허용되는 형식인지 확인합니다.
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
e.stopPropagation();
setDragActive(false);
const files = e.dataTransfer.files;
if (!files.length) return;
if (!multiple && files.length > 1) {
setError("Only one file is allowed");
return;
}
const acceptedTypes = accept ? accept.split(",") : [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const isValidFileType = acceptedTypes.some((type) => {
const regex = new RegExp(type.replace("*", ".*"));
return regex.test(file.type);
});
if (accept && !isValidFileType) {
setError(`Invalid file type: ${file.name}`);
return;
}
}
setError(null);
onFileSelect(files);
};
파일 입력 대체 수단
클릭을 통한 파일 업로드를 선호하는 사용자를 위한 숨겨진 파일 입력 필드를 제공합니다. triggerFileSelect 함수는 업로드 영역을 클릭하면 파일 대화상자를 자동으로 엽니다.
const triggerFileSelect = () => {
inputRef.current?.click();
};
Tailwind와 DaisyUI
드롭 영역은 DaisyUI 클래스를 사용해 스타일링되며, dragActive 상태에 따라 파일이 드래그될 때 테두리 색상이 변경됩니다.
<div
onDragEnter={handleDrag}
onDragOver={handleDrag}
onDragLeave={handleDrag}
onDrop={handleDrop}
className={`${className} border-2 border-dashed p-6 rounded-lg text-center cursor-pointer transition-colors ${
dragActive ? "border-primary" : "border-base-50 bg-base-200"
}`}
onClick={triggerFileSelect}
>
<input
ref={inputRef}
type="file"
className="hidden"
multiple={multiple}
accept={accept}
onChange={handleChange}
/>
<p className="text-base-content/50">
{multiple
? "Drag & Drop files here or click to upload multiple files"
: "Drag & Drop a file here or click to upload"}
</p>
</div>
에러 메시지 표시
업로드된 파일에 문제가 있을 경우, 업로드 영역 아래에 에러 메시지를 표시합니다.
{
error && <p className="text-xs text-error mt-2">{error}</p>;
}
이러한 방식으로 React와 Next.js를 활용해 사용자 경험을 향상시키고, 효율적이며 깔끔한 파일 업로드 기능을 구현할 수 있습니다.