개인프로젝트를 하면서 겪었던 어려움과 전에도 했었는데
기억이 잘 안나 다음에 조금 더 쉽게 꺼내먹기 위한 정리노트
<input type = "file" />
생각보다 잘 사용하게 되는 것 같다.
현재로썬 이미지 업로드 할 때 가장 먼저 떠오르는 태그이기도 하다.
근데 조금 못생겼다..
단순하게 이렇게 쓸 수 있지만 아무래도 내가 어떤 이미지를 올렸는지
미리보기(썸네일)이던가 서비스의 스타일에 맞지 않을 수 있기에
커스터마이징은 필수이다 .
mdn에 꽤나 자세히 적혀있으니 읽어보는것도 재밌다🖍
click → 웹어플리케이션에서 파일사용하기
내가 구현한 두가지 방식
1. 커스터마이징
2. 미리보기만들기
순으로 본론 들어가보자
/* css */
.photo-wrapper > label {
font-size: 2em;
display: inline-block;
background-color: #ffffff;
width: 100%;
height: 100%;
text-align: center;
line-height: 6;
cursor: pointer;
color: black;
}
input[type='file'] {
opacity: 0;
}
//react
<label htmlFor={`photo${num}`}>+</label>
<input type="file" accept="image/*" id={`photo${num}`} name="photo" onChange={photoChangeHandler} />
이런식으로 file 타입을 숨기고 label로 디자인을 하는 방법!
으로 했다.
file 타입에 대해선 다양하게 사용하기도 하는데 나는 깔끔하게 opcaity를 줄이는 걸 선호한다.
대신 hidden을 해버리면 파일 업로드가 안된다!
어려워... 어려워....
{썸네일 이미지}
이런 방식이면 꽤나 간단하게 할 수 있는데
내가 원한 미리보기 형태는
선택파일 위에 이미지를 올리는 방식이라 css를 조금 감미하여 구현했다.
const photoChangeHandler = (event: React.ChangeEvent<HTMLInputElement>): void => {
event.preventDefault();
if (event.target.files === null) return;
const reader = new FileReader();
const file = event.target.files[0];
reader.onloadend = () => {
setPhotoInfo({
file: file,
previewImg: reader.result as string,
});
};
reader.readAsDataURL(file);
};
return (
<>
<div className="photo-wrapper">
<label htmlFor={`photo${num}`}>+</label>
<input type="file" accept="image/*" id={`photo${num}`} name="photo" onChange={photoChangeHandler} />
{photoInfo.previewImg && <Image src={photoInfo.previewImg} photoInit={photoInit} />}
</div>
</>
);
컴포넌트 일부 코드를 발췌했다.. 잘쓰고있는지는 모르겠는데.. 나름 노력했다..
TS + React로 하는 중이라 꽤나 골머리가 아프다.. 어렵다..
가장 중요한건 FileReader() 와 files[0]이지 않을까 싶다.
type file의 리턴값이 FileList이고, FileReader로 불러오는 방식으로 했다.
이런방식으로 +있는 label부분을 눌러서 파일을 선택하면
라벨위에 이미지를 올려서 미리보기가 가능하게 한 상태다.
추가로 x 버튼을 만들어서 이미지도 없애서 다시 선택할 수 있도록 해놨다..!
파일만 읽어오면 원하는 방식으로 미리보기이미지를 만들 수 있을 것 같다 : )
FileReader에 대해선 따로 더 알아볼 예정이다 !
총 4개의 사진 컴포넌트를 만들어서 적용했는데 계속 한개에만 이미지가 적용되길래
뭔가 싶었는데 POOP.. 라벨 id를 다똑같이 만들어놓고 고민했다...ㅎ...
For- id를 잘 맞추자...
//수정전
<label htmlFor="photo">+</label>
<input type="file" accept="image/*" id="photo"name="photo"/>
//수정후
<label htmlFor={`photo${num}`}>+</label>
<input type="file" accept="image/*" id={`photo${num}`} name="photo"/>