[next/ts] react-dropzone으로 이미지 업로드 및 미리보기 구현하기

inguk·2023년 11월 15일
0

팀프로젝트

목록 보기
2/3
post-custom-banner

오늘은 진행중이던 프로젝트에서 공연 썸네일등록 위해 사용한 react-dropzone 라이브러리 내역을 기록하려고합니다.

react-dropzone

react-dropzone은 React에서 파일 드래그 앤 드롭 기능을 쉽게 구현할 수 있게 해주는 라이브러리입니다. 사용자가 파일을 드래그나 직접 업로드하며 사용이 가능하며 제가 제공받은 api는 multipart/form-data이기때문에 기본 json이 아닌 form-data로 한번 변환후에 링크만 출력해서 사용할 예정입니다

.

import { useDropzone } from "react-dropzone";

const {
  getRootProps,
  getInputProps,
} = useDropzone({
  accept: {
    "image/*": [".jpeg", ".jpg", ".png"],
  },
});

기본 설정

먼저, react-dropzone을 사용하기 위해 필요한 기본 설정입니다

  • useDropzone 훅을 사용하여 드롭존을 설정합니다.
  • accept 속성을 통해 업로드 가능한 파일 형식을 지정할 수 있습니다. JPEG, JPG, PNG 형식을 지정해주면 해당 확장자의 이미지 파일만을 허용합니다.

썸네일 이미지 업로드 구현

다음으로 썸네일 이미지를 업로드하는 부분을 구현해보겠습니다.

const onDropThumbnail = useCallback((acceptedFiles: File[]) => {
  const file = acceptedFiles[0];
  //file 첫번째 파일을 저장합니다
  const fileURL = URL.createObjectURL(file);
  //createObjectURL는 임시로 URL을 저장할수 있는 메서드입니다
  setThumbnailPreview({ url: fileURL, name: file.name, size: file.size });
}, []);

onDropThumbnail 함수는 사용자가 드롭존에 이미지를 놓았을 때 호출됩니다.
선택된 첫 번째 파일을 thumbnailPreview 상태에 저장한 후 파일의 URL, 이름, 크기를 관리할 수 있습니다.
URL.createObjectURL 함수를 사용하여 파일의 미리보기 URL을 생성합니다.

다중 이미지 업로드 구현

const onDropImages = useCallback((acceptedFiles: File[]) => {
  const mappedFiles = acceptedFiles.map((file) =>
    Object.assign(file, {
      preview: URL.createObjectURL(file),
    })
  );
  setImagesPreview([...imagesPreview, ...mappedFiles]);
}, [imagesPreview]);

onDropImages 함수는 사용자가 여러 이미지 파일을 map메서드와 Object.assign메서드로 이미지 배열 구현이 가능합니다
onDrop은 acceptedFiles를 인자로 받을 수 있는데 map을 사용하여 여러 이미지를 받고
URL.createObjectURL와 Object.assign로 객체를 복사해서 구현했습니다

이미지 삭제

const removeFile = (fileToRemove: FileWithPreview | Preview) => {
  if ("preview" in fileToRemove) {
    setImagesPreview((prevFiles) =>
      prevFiles.filter((file) => file.preview !== fileToRemove.preview)
    );
    URL.revokeObjectURL(fileToRemove.preview);
  }
};

removeFile 함수는 특정 파일을 삭제할 때 사용됩니다.
파일의 미리보기 URL을 사용하여 해당 파일을 imagesPreview 상태에서 제거 후
URL.revokeObjectURL 함수를 사용하여 더 이상 필요하지 않은 URL을 해제합니다

이미지 업로드

  const uploadFiles = async (e: any) => {
    e.stopPropagation();
    try {
      if (!thumbnail || images.length === 0) {
        alert("썸네일과 이미지 파일을 모두 추가해주세요.");
        return;
      }
      setUploading(true);
      const response = await postEventImageApi(atk, thumbnail, images);
      setThumbNailUrl(response.data.thumbNailImageUrl);
      setImageUrls(response.data.imageUrls);
      setUploading(false);
    } catch (error) {
      console.error("이미지 업로드 중 에러 발생:", error);
    }
  };

<Button type="button" onClick={uploadFiles}>
  이미지 업로드
</Button>

제공받은 api에 formdata를 보내 링크를 생성받으면 setThumbNailUrl과 setImageUrls에 상태를 보관해서 사용이 가능합니다

formdata api를 처음사용해봐서 끝나고나니 별로 어렵다고 느껴지진않았는데 이래서 삽질도 경험이 필요한가봅니다.. 여기까집니다

profile
Frontend
post-custom-banner

0개의 댓글