본문 바로가기

TIL

TIL 24.06.14 react-dropzone & FormData 데이터 전송

구현 기능

내가 구현해야 할 기능은 드래그앤 드롭으로 사진을 첨부하는 기능과 이 사진데이터들을 서버로 보내주는 기능이었다.

 

드래그앤 드롭 사진첨부 기능

- 이미지 파일 업로드

- 무슨 이미지를 올렸는지 확인할 수 있는 thumbnail

- 올리는 이미지 갯수 제한

- 올리는 이미지 용량 제한

 

formData 형태로 서버에 전송하는 기능

- 업로드 된 이미지를 formData 형태로 변경하기

- content-type을 설정해주고 서버로 데이터 알맞게 전송하기

 

 

1. 드래그앤 드롭 사진첨부 기능

 

이미지 파일 업로드

이 기능은 javascript 에서 구현해본 경험이 있었다. 그당시에는 라이브러리를 사용하지 않고 구현했는데, react 에서 제공하는 react-dropzone 을 사용해보기로 하였다.

 

우선 라이브러리를 다운받아준다.

npm install --save react-dropzone

 

이미지를 업로드 할때 maxFiles 프로퍼티가 있어서 개수 제한을 두기 편리했다.

허용가능한 이미지 타입도 지정할 수 있다.

 

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

 

 

thumbnail 구현하기

이렇게 받아온 이미지는 onDrop 에서 다룰 수 있는데,

window.URL.createObjectURL() 은 메모리상의 객체에 임시 url 을 생성할 수 있는 메서드 이다.

 

다음과 같이 preview 라는 key를 가진 이미지의 임시 url 을 생성하였다.

onDrop: (acceptedFiles) => {
        const newImages = acceptedFiles.map((file) =>
          Object.assign(file, {
            preview: URL.createObjectURL(file),
          })
        );
}

 

 

이미지 용량 제한

업로드하는 이미지의 용량이 10mb를 초과하면, 업로드를 금지했다.

let totalSize = 0;
 
newImages.forEach((image) => (totalSize = totalSize + image.size));

if (totalSize > 1024 ** 2 * 10) {
    ToastError(TOAST_TEXT.IMAGE_SIZE_MAX_ERROR);
    return;
}

 

 

이미지 개수제한

if (images.length + newImages.length > 5) {
    ToastError(TOAST_TEXT.IMAGE_COUNT_ERROR);
    return;
}

 

 

 

2. formData 형태로 서버에 전송하는 기능

 

이제 올려진 이미지를 formData 형태로 서버에 전송해야 한다. 처음 해보는 기능이어서 조금 헤맸던 것 같다.

 

formData를 객체를 생성하고 다음과같이 이미지를 폼데이터에 담아준다.

const formData = new FormData();

    images.forEach((image, index) => {
      formData.append(`images`, image);
    });

 

 

데이터를 최종적으로 전송할 때, 나같은 경우 api에 url 까지 작성하고 첫번째 인자를 작성하지 않고 formData만 전송해서 다음과 같이 에러가 났다. 

TypeError: relativeURL.replace is not a function

 

 

url 이 들어갈 자리에 formData 가 들어갔으니 타입에러가 날 수 밖에 없었다. 요청 url 을 굳이 안보내도 되는 경우라면 그 자리에는 "" 로 문자열임을 확인할 수 있는 url 이 들어가야 한다.

export const sendFormData = async (formData) => {
  const response = await api.post("요청 url", formData);
  return response.data;
};

 

 

이 기회를 통해 폼 데이터를 전송하는 방식에 대해서 많이 배운 것 같다.

axios.post('url', formData, config);