[React] 이미지 업로드 / 미리 보기

김정현·2022년 11월 7일
0

기타

목록 보기
7/25

input

<input 
  type="file" // 파일을 업로드 할 수 있는 타입이다
  accept="image/ *" // 파일의 종류와 확장자를 지정한다
  name="inputName" // 콜백에서 event.target.inputName으로 업로드 된 파일 정보를 사용할 수 있다
  id="inputId" // label과 연결할 때 사용한다
  multiple // 여러 개의 파일을 업로드 할 수 있다
  onChange={inputCallback}> // file 선택 시 이벤트 콜백을 실행한다
</input>

업로드한 이미지값 찾기

  1. event.target.inputName
  2. event.target.files (files는 객체 형식)

외부 태그에서 input 실행하기

input type="file"의 기본 외형을 변경할 수 없기 때문에
input을 display: none으로 숨긴 뒤,
외부 태그로 연결해서 사용하는 방식을 주로 사용한다

label

label의 for속성에 연결할 input의 id를 넣어주면 연결된다
className을 통해 style값을 조절하여 원하는 외형으로 커스텀할 수 있다

<label className="inputLabel" for="inputId"></label>

button

input에 id를 부여하고, 선택자를 통해 input을 찾아서
외부에서 클릭 이벤트를 실행시킬 수 있다

function clickEvent() {
  document.querySelector('#inputId').click();
}

<input id="inputId" onClick={clickEvent}></input>
<button onClick={clickEvent}></button>

FormData()

const formData = new FormData();

formData.append('key', value);
formData.delete('key', value);
formData.get('key', value);
formData.entries('key', value);

서버로 파일을 보낼 때 사용하는 객체이다
formdata의 내용은 콘솔에서 확인할 수 없고, formdata{}로만 출력된다
따라서 formdata.keys(), formdata.values()등으로 배열화 한 뒤
key나 value를 확인하거나 배열함수를 사용하여 활용할 수 있다

form 기본 전송 기능을 사용하는 경우,
fetch의 header에서 'Content-Type': 'multipart/form-data'를 사용한다

⚠️ 파일과 text를 한 번에 전송해야 하는 경우, 
⚠️ text와 파일정보를 FormData에 모두 append한 뒤 FormData를 body에 담아서 보내야 한다

선택한 이미지 미리보기

FileReader, onload 이벤트, readAsDataURL()를 이용하여
input으로 받은 file의 정보를 바로 사용할 수 있도록 가공할 수 있다

const [previewImg, setPreviewImg] = useState(null);

<input
  type="file"
  accept="image/*"
  onChange={onImgChange}
></input>

//파일 가공
function onImgChange(event) {
  let reader = new FileReader();
  let file = event.target.files[0];
  
  reader.onloadend = () => {
    setPreviewImg(reader.result);
  };
  reader.readAsDataURL(file); 
}

//가공한 파일 사용
<div
  className="previewImg"
  style={{
    backgroundImage: `url(${previewImg})`,
    backgroundSize: 'cover',
  }}
></div>

FileReader()

FileReader.readAsDataURL()
특정 Blob이나 File에서 읽어 오는 역할을 한다.
다 읽고 난후 result속성에 결과가 담아진다.

BLOB

파일류의 불변하는 미가공 데이터


URL.createObjectURL


통신 시 발생하는 에러

  1. Error: Multipart: Boundary not found( Multer - fetch 파일 전송 에러 )
event.preventDerault()를 통해 form의 기본 전송을 막은 뒤,
fetch를 통해 직접 파일 전송을 구현한다면 

1. form 태그에 encType="multipart/form-data" 속성을 추가한 뒤
2. fetch의 headers를 비우고 
3. body에 FormData를 담아 전송하여 해당 에러를 해결할 수 있다\

참조:
https://velog.io/@gay0ung/리액트로-이미지-업로드-미리보기
https://developer.mozilla.org/ko/docs/Web/API/FileReader
https://curryyou.tistory.com/466

profile
개발 공부 블로그

0개의 댓글