쇼핑몰 프로젝트를 진행하면서 스타일 공유 커뮤니티 페이지에서 이미지 업로드 / 미리보기를 처음으로 구현해보았다.
이미지 업로드 / 미리보기는 프로필, 게시글 등 다양한 곳에서 사용될 수 있기에 라이브러리도 있지만 직접 구현해보고 공부한 내용을 기록해보려 한다.
1. FileReader |
Web API로 FileReader는 File, Blob 객체가 저장하고 있는 바이너리 데이터를 '비동기적'으로 읽어주는 객체이다.
기본동작은 read - load Event - result 의 과정을 거친다.
FileReader 객체를 생성한 후에 readAsDataURL()은 File 또는 Blob을 읽은 뒤 base64로 인코딩된 문자열을 result 라는 속성에 담는다.
onload()는 성공적으로 파일을 읽었을 때 실행되는 이벤트핸들러인데 onload()를 실행하는 Promise 객체를 return한다.
핸들러 내부에는 reader.result 안에 담긴 문자열을 image 상태값에 업데이트 해준다.
reslove를 호출한 뒤 input의 onChange에 함수를 넣어주면 된다.
function TrendInput() {
const [image, setImage] = useState<any>(null);
const saveImage = (e: any) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
return new Promise<void>((resolve) => {
reader.onload = () => {
setImage(reader.result || null);
resolve();
};
});
};
return (...
<>
<Button htmlFor="imgUpload">이미지 업로드</Button>
<Input type="file" id="imgUpload" accept="image*" onChange={(e) => saveImage(e)} />
</>
{/* 이미지 영역 */}
<ImageWrapper>
{image ? (
<Image src={image} alt="사용자 업로드 이미지" />
) : (
<NoImage src={uploadImage} />
)}
</ImageWrapper>
)}
결과는!
2. 후기 |
블로그를 쓰고 기록을 하면서 공부를 하기 위해 찾아보던 중에 FileReader() 방식이 아닌 다른 createObjectURL 을 사용하는 방식 찾을 수 있었다. 각 방식의 장단점을 확인할 수 있었는데 공부 후에 비교를 통해 블로그에 다시 한번 정리해야겠다고 생각했다. 체크 해놓아야겠다.
블로그에 기록을 하면서 공식 문서나, 글들을 찾아보면 지금 쓰고 있는 내용 외에 공부되는 것들이 많은 것 같다.
