Daily Front_Minhhk

[React] 파일 다운로드 훅_blob filedown hook 본문

Code개발일지

[React] 파일 다운로드 훅_blob filedown hook

Minhhk 2024. 12. 8. 12:34
import { useState } from "react";
import useToast from "@/hooks/toast/useToast";

const useFileDownload = () => {
  const toast = useToast();
  const [isDownloading, setIsDownloading] = useState<boolean>(false); // 다운로드 상태 관리

  //! 파일 미리보기
  const handleFileView = (fileUrl: string) => {
    if (!fileUrl) return console.error("파일이 없습니다");
    window.open(fileUrl, "_blank");
  };

  //! 파일 다운로드
  const handleFileDownload = async (fileUrl: string) => {
    if (!fileUrl) {
      console.error("파일이 없습니다");
      return;
    }

    const encodedFileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
    const decodedFileName = decodeURIComponent(encodedFileName); // 한글 디코딩

    try {
      toast("다운로드 진행중입니다.", "success");
      setIsDownloading(true); // 다운로드 시작 상태

      const response = await fetch(fileUrl);
      const blob = await response.blob();

      // Blob > fileDown 강제 다운로드
      const link = document.createElement("a");
      const blobUrl = URL.createObjectURL(blob);
      link.href = blobUrl;
      link.download = decodedFileName; // 디코딩된 파일명으로 다운로드
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(blobUrl); // 메모리 정리

      setIsDownloading(false); // 다운로드 완료 상태
    } catch (err) {
      toast("다운로드에 실패했습니다.", "warning");
      setIsDownloading(false); // 실패시 상태 변경
      console.error(err);
    }
  };

  return { handleFileView, handleFileDownload, isDownloading };
};

export default useFileDownload;

 

 

 

  • 사용 컴포넌트에서 훅으로 꺼내와서 링크
const { handleFileView, handleFileDownload, isDownloading } = useFileDownload();

const handleFileDown = (fileUrl : string) => {
	// 다운받을 url 넣어서 사용ㄱㄱ
}

// handleFileView 마찬가지로

// return 하위에 로딩 표시 할려면 {isDownloading && <div>loading 알아서 사용</div>}

 

 

  • toast 는 react-toast 를 훅으로 사용