react S3 Image Upload

김대은·2022년 8월 21일
1

S3 버킷 생성 참조

S3 란?

Simple Storage Service의 약자로 내구성과 확장성이 뛰어난 스토리지 서비스이다.

upload 하는법

npm i reacet-asw-s3
import S3upload from 'react-aws-s3'

  • upload
    const submitBtn = (e) => {
       e.preventDefault();
       let file = fileUpload.current.files[0];
       let newFileName = fileUpload.current.files[0].name;
       const config = {
         bucketName: process.env.REACT_APP_BUCKET_NAME,
         region: process.env.REACT_APP_REGION,
         accessKeyId: process.env.REACT_APP_ACCESS_ID,
         secretAccessKey: process.env.REACT_APP_ACCESS_KEY,
       };
       const ReactS3Client = new S3upload(config);
       ReactS3Client.uploadFile(file, newFileName).then(data => {
         if(data.status === 204) {
           let imgUrl = data.location
           dispatch(addRecordDB(recordDate, imgUrl))
         } else {
           window.alert('사진 업로드에 오류가 있어요! 관리자에게 문의해주세요.')
         }
       });
     }

위 함수 config에 보면 aws의 accesskey와 보안키가 들어간다.
이 부분은 aws에서 생성해야한다.
여기서 주의가 필요한 부분은 이 보안키는 절대 외부로 노출되어서는 안되는데 처음 .env파일을 만들어서 그 안에 저장하고
절대 git에는 올리지 않도록 gitignore 에 반드시 추가하자

Image Preview

const [fileUrl, setFileUrl] = useState(null);
	//인풋이 onChange 될 때
const chgPreview = (e) => {
  //현재 이미지 파일
   const imageFile = e.target.files[0];
  //선택한 이미지 파일의 url
   const imageUrl = URL.createObjectURL(imageFile);
  //Image ele의 src를 해당 이미지 url로 변경시켜준다.
   setFileUrl(imageUrl)
 }

Image Resizing

이미지를 리사이징 하는 이유는 뷰에 그려주는 문제가 아니라
해당 이미지가 로드될 때의 성능을 위해서 이다.
용량이 클수록 클라이언트에 보여주기 위한 로딩 시간이 길어질테니
이를 줄여주기 위해 리사이징을 한다.

npm i browser-image-compression
import imageCompression from "browser-image-compression";

아래 코드는 Image Preview 와 Image Resizing 이 합쳐진 코드이다.

//const options = { 
 //maxSizeMB: number,          // (default: Number.POSITIVE_INFINITY)
 //maxWidthOrHeight: number,   // compressedFile will scale down by ratio to a point that width or height is smaller than maxWidthOrHeight (default: undefined)
 //onProgress: Function,       // optional, a function takes one progress argument (percentage from 0 to 100) 
 //useWebWorker: boolean,      // optional, use multi-thread web worker, fallback to run in main-thread (default: true)

 // following options are for advanced users
 //maxIteration: number,       // optional, max number of iteration to compress the image (default: 10)
 //exifOrientation: number,    // optional, see https://stackoverflow.com/a/32490603/10395024
 //fileType: string,           // optional, fileType override
 //initialQuality: number      // optional, initial quality value between 0 and 1 (default: 1)
//}

const options = {
   maxSizeMB: 1,
   maxWidthOrHeight: 1920,
   useWebWorker: true
 }

 const imgUpload = useRef();
//+ input(type=file)의 onChange 함수
 const onChangeImage = async (e) => {
   const imageFile = e.target.files[0];
   const options = {
     maxSizeMB: 1,
     maxWidthOrHeight: 1920,
     useWebWorker: true,
   };
   try {
     const compressedFile = await imageCompression(imageFile, options);
     const imageUrl = URL.createObjectURL(compressedFile);
     setFileUrl(imageUrl);
   } catch (error) {
     console.error(error);
   }
 };
profile
매일 1% 이상 씩 성장하기

0개의 댓글