React - axios를 이용해 댓글에 이미지 업로드 해보기

Shin Yeongjae·2020년 8월 17일
13

Wecode

목록 보기
25/26

axios를 이용해 이미지 업로드 해보기라고 적었지만 fetch를 이용하는 것도 방법은 똑같다.
둘 다 multipart/form-data를 이용하면 간단하게 할 수 있다.

multipart/form-data는 파일 업로드가 있는 양식요소에 사용되는 encType 속성의 값중 하나이고, multipart는 form data가 여러 부분으로 나뉘어 서버로 전송되는것을 의미한다.

<CommentInput
  name="photo"
  encType="multipart/form-data"
  onSubmit={handleSubmit}
>
  <input
    type="file"
    name="photo"
    accept="image/*,audio/*,video/mp4,video/x-m4v,application/pdf,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,.csv"
    onChange={handleUpload}
  />
    ...

styled-component를 이용해서 안보이지만 form 태그로 생성을 해야한다. 그리고 encType을 multipart/form-data로 지정해주면 된다. 이 form이 제출될 때 어떤 형식인지를 알려주는 것이다. 그리고 input에 필요한 이벤트핸들러를 만들어 주면 된다. 아 그 전에 어떤 파일들이 올라갈지 accept라는 attribute를 지정해줘야 한다.

  const handleSubmit = (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("photo", files.length && files[0].uploadedFile);
    formData.append("comment", commentValue);
    formData.append("content_id", classData.content_id);

    axios({
      method: "post",
      url: STREAMING_COMMENT_URL,
      data: formData,
      headers: { "Content-Type": "multipart/form-data", Authorization: localStorage.getItem("access_token") }
    });
    setCommentValue("");
    setFiles([]);
  };

  const handleUpload = (e) => {
    e.preventDefault();
    const file = e.target.files[0];
    setFiles([...files, { uploadedFile: file }]);
  };

handleUpload 함수에 보면 const file = e.target.files[0]이라고 선언된 것을 볼 수 있다. 참고로 e.target.file은 배열이 아니다. 그런데 어떻게 index로 접근을 하고 있을까?

file은

fileList: {
  0: {name: file1, ...},
  length: 1,
  item: {...}
}

이런식으로 구성되어 있다. 우리가 필요한 것은 파일이기 때문에 0라는 키에 접근한 것이다.

어쨌든, 이제 submit 이벤트를 발생시켜야 하니 함수를 작성해주자.

form 태그는 a 태그와 마찬가지로 페이지를 reload 시키기 때문에 먼저 preventDefault를 해주고 새로운 FormData를 생성해준다.
그리고 백엔드에 보내기 위해 필요한 data들을 formData에 key value 형태로 append 시켜준다. 여기까지 하면 준비완료.

그리고 axios 요청을 백엔드 API로 보내면 된다. 모든것은 백엔드가 요구한대로... data라는 키에만 아까 만든 formData를 담아주면 된다.

그리고 setCommentValue("")setFiles([])는 이벤트 발생 후 업로드된 파일과 댓글 내용을 초기화시켜주기 위한것이니 크게 신경쓰지 않아도 된다.

아주 간단하게 multipart/form-data 적용 성공

profile
문과생의 개발자 도전기

2개의 댓글

comment-user-thumbnail
2020년 11월 24일

안녕하세요! 이미지 업로드를 찾아보던 중 유일하게 백엔드 서버에 보내는 글을 발견하여 글남깁니다! 해주신대로 잘 따라하고 있는데 axios안에 url은 무엇인가요? 지금 fetch를 이용하고 있느데 fetch에 API라고 봐도 되나요? 좋은 글 감사합니다!

1개의 답글