UNIVE.US: React, 이미지 미리보기 구현(FileReader API)

이번 프로젝트에서 프로필 관리의 기능 중에 프로필 이미지를 입력하면 해당 이미지가 어떻게 적용되는지 미리보는 기능이 필요했다. 해당 기능은 글 가장 하단의 블로그 내용을 참고하여 구현하였다.

input type=’file’


일단 이미지 파일을 받기 위해서 input 태그의 type을 file로 하여 이미지를 받는다.
이때, label도 같이 작성해주는데 input 태그의 기본 스타일을 안보이게 하고 내가 원하는 스타일의 버튼을 label에 적용해주기 위해서이다. 그렇게에 label의 htmlFor의 값과 input의 id 값을 동일하게 작성해줘야 한다. 그래야 label을 클릭했을 때, input 태그를 누르는 것과 동일한 액션을 취한다.

<label htmlFor="mypage-profile-img">
  프로필 수정
</label>
<input
  type="file"
  accept="image/*"
  id="mypage-profile-img"

input 태그의 속성으로 accept을 작성해준다. accept 속성은 input 태그의 type이 file인 경우에만 작성이 가능하며, 해당 속성은 파일의 타입을 명시한다.
위의 코드에서 작성한 accept의 값인 image/*는 모든 타입의 이미지 파일의 업로드가 허용됨을 뜻한다.

스타일 수정


input 태그를 보이지 않게 하고, label에 원하는 스타일을 적용시킨다.
input 태그에 display:none; 를 작성하여 보이지 않게 하였다.

  • 프로필 관리 (이미지 업로드 전)

    이미지 미리보기 스타일

미리보기 기능 구현


이미지 업로드 input 태그에 넣을 onChange

saveImgFile 함수는 FileReader API를 사용하여 이미지를 업로드하는 input 태그의 onChange 이벤트로 넣을 함수이다.
이때, readAsDataURL은 파일을 URL로 만들어준다(FileReader API).

FileReader API?
웹 API로, 비동기적으로 데이터를 읽기 위하여 File(읽을 파일을 가리킴) 혹은 Blob 객체를 이용해 파일의 내용을 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 함
즉, 클라이언트단에서 file이랑 blob 사용할 수 있게 해주는 것

onChange?
input 태그의 포커스에서 벗어났을 때 (즉, 입력이 종료했을 때) 발생하는 이벤트

  • saveImgFile

    imgRef에서 가장 최근의 파일을 불러와 file에 저장
    reader은 FileReader 객체 생성
    reader에 readAsDataURL 함수를 통해 file을 URL로 반환(즉, 해당 이미지 파일의 링크가 생성됨)
    읽기 성공, 실패 여부 상관없이 동작이 끝났을때 마다(reader.onloadend), 파일의 내용을 반환(reader.result)

import { useState, useRef } from 'react';
import defaultImg from 'default 이미지 경로';

const [imgFile, setImgFile] = useState('');
const imgRef = useRef();

...

// 이미지 업로드 input 태그에 넣을 onChange
const saveImgFile = () => {
  const file = imgRef.current.files[0];
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onloadend = () => {
    setImgFile(reader.result);
  };
};

...

// 이미지 미리보기
<img
  src={imgFile ? imgFile : defaultImg}
  alt="프로필 이미지"
/>

...

// 이미지 업로드
<label htmlFor="mypage-profile-img">
  프로필 수정
</label>
<input
  type="file"
  accept="image/*"
  id="mypage-profile-img"
  onChange="{saveImgFile}"
  ref="{imgRef}"
/>

이미지 미리보기

img 태그의 src 속성 값으로 삼항연산자를 사용했다. imgFile의 값이 true일 경우 imgFile을 src 속성의 값으로 한다. 그러나 false일 경우에는 defaultImg를 src 속성의 값으로 한다.
이 말인 즉, 이미지를 업로드 하면 해당 이미지를 보여주고 이미지를 업로드 하지 않았다면 기본 이미지(defaultImg)를 보여준다는 뜻이다.

이미지 업로드

input 태그에 위의 코드에 새로운 속성을 더 추가를 해준다. onChange 속성을 추가하여 input 태그의 입력이 종료했을 경우 saveImgFile 함수를 실행한다. ref 속성의 값은 imgRef 를 작성한다.

  • 이미지 업로드

    이미지 파일 선택

  • 이미지 미리보기 구현 완료

    이미지 미리보기 구현 완료

마치며


다른 분의 코드를 참고하여 구현하긴 했지만, 정상적으로 기능이 작동하도록 만들어서 뿌듯했다.
구현을 완료하고 이미지가 이쁘게 잘 들어가는 모습을 보니 매우 기쁘달까..! 이렇게 새로운 것을 알게되어서 재밌다.
개발 공부는 힘들고 어렵지만 완벽히 습득을 하고 나면 정말 무궁무진하게 활용할 수 있어서 질리지 않고 재밌는 것 같다.

참고
React : 이미지 업로드하고 미리보기
FileReader로 브라우저에서 file 다루기
파일API : FileReader() 객체

Comments