파일을 업로드하여 졸업 여부를 확인하는 기능을 작성하던 중,
클릭으로 올리는 기능 이외에도 드래그 앤 드랍으로 파일을 핸들링할 수 있으면 사용자 편의성에 있어 좋을 것 같다는 생각이 들어서 구현하고자 했습니다.
드래그 앤 드랍 기능을 추가하기 위해서는 아래와 같은 방법이 필요합니다.
const [isActive, setActive] = useState<boolean>(false);
const handleDragStart = () => setActive(true);
const handleDragLeave = () => setActive(false);
const handleDragOver = (event: React.DragEvent) => {
event.preventDefault();
setActive(true);
};
const handleDrop = (event: React.DragEvent) => {
event.preventDefault();
setActive(false);
const file = event.dataTransfer.files[0];
if (file) {
uploadFile(file);
}
};
const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
uploadFile(file);
}
};
const uploadFile = (file: File) => {
setActive(true);
const fd = new FormData();
fd.append("file", file);
axios
.post(`${api.graduate}`, fd, {
headers: {
"Content-Type": `multipart/form-data`,
Authorization: `Bearer ${cookies.accessToken}`,
},
})
.then((response) => {
setGraduateData(response.data.data);
})
.catch((error) => {
setMessage(error.response.data.message);
setIsOpen(true);
setActive(false);
});
};
// code..
<Label
onDragEnter={handleDragStart}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
isActive={isActive}
>
<Image backgroundImage={GraduateImage}>
<Input
type="file"
accept=".pdf"
id="file"
name="file"
onChange={handleFileInputChange}
/>
<FileButton>
<File width={30} height={30} fill="white" />
<p>학업성적확인서 PDF 업로드</p>
</FileButton>
</Image>
</Label>
isActive
: 드래그 앤 드롭 영역에 마우스가 있을 때 활성화 여부를 나타냄handleDragStart
, handleDragLeave
: 드래그 앤 드롭 영역위에 마우스가 들어오고 나갔을 때 호출되는 함수 handleDragOver
: 드래그 앤 드롭 이벤트 처리 함수 handleDrop
: 드래그 앤 드롭으로 파일을 업로드 하는 함수 handleFileInputChange
: 파일 입력이 변경되었을 때 호출되는 함수uploadFile
: 파일을 서버에 업로드하고 응답을 처리하는 함수