input type file에 관하여..

juu·2023년 3월 21일
0

photo4, A to Z

목록 보기
2/2
post-thumbnail

개인프로젝트를 하면서 겪었던 어려움과 전에도 했었는데
기억이 잘 안나 다음에 조금 더 쉽게 꺼내먹기 위한 정리노트

<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"/> 

0개의 댓글