input 사용해서 이미지 파일 보내기 총 정리

피시본·2022년 12월 2일
1
post-thumbnail

타입스크립트, 리액트, 비트를 사용해 프로젝트를 하고 있다. 사용자 기본 프로필 이미지를 임의로 넣어주고 사용자가 그 이미지를 수정하는 코드를 짜다 한번에 정리해두면 좋을 것 같아 벨로그를 켰다.

input으로 이미지 파일 넣기

사진을 넣을 input의 타입을 file로 지정한다. 이미지 파일만 받고 싶으면 accept="image/*"로 적어주면 된다.

<input
	type = "file"
    accept = "image/*"
/>

그러면 자동으로

이렇게 파일을 선택할 수 있게 된다. 그런데 이 파일을 어디서 보지? 옆에 미리보기를 할 수 있는 div를 짜두었는데 선택한 이미지 파일을 그 안에 어떻게 띄울까?

프로필 이미지 미리보기

const [communityImage, setCommunityImage] = useState<string | ArrayBuffer | null>
(`${import.meta.env.VITE_PUBLIC_URL}/img/default_image3.png`);

이미지가 바뀌는 요소이니 useState 훅을 사용한다. 기본 프로필 이미지는 아직 퍼블릭 도메인 주소가 없기에 로컬 주소를 넣어 사진을 넣었다.

  • 여기서 꿀팁: 기본으로 만들어지는 public 폴더 안에 img 폴더를 만들어 이미지를 넣으면 안에 든 이미지를 부를 때 앞에 import할 파일이나 폴더를 구구절절 적지 않아도 된다. /img/이미지명.확장자만 써주면 바로 불러진다.

파일을 div 안에 넣기 전에 먼저 파일 선택으로 가져온 이미지를 읽어야 한다.

const handleChangeFile = (e: React.ChangeEvent<HTMLInputElement>) 
=> {
    if (e.target.files) {
      const file = e.target.files[0];
      const reader = new FileReader();
      reader.readAsDataURL(file);

      reader.onload = () => {
        setCommunityImage(reader.result);
      };
    }
  };

저 file을 콘솔에 찍어보면 이미지 명이 나온다. 이걸 파일리더로 읽어 앞에 정의해둔 set함수에 넣어준다.

그리고 맨 앞에 쓴 input 부분에 onChange={handleChangeFile}를 추가한다.

이렇게 읽힌 파일을 div에 넣는 방법은 간단하다.

{communityImage && (
              <img src={communityImage.toString()} 
              className="pre-img" />
            )}

여기서 애를 먹은 게 src={communityImage} 라고만 적었는데 계~~~속 파일 형식이 안 맞는다고 에러가 뜨는 거다. 타입스크립트를 처음 써봐서 더 우왕좌왕 ... 이것저것 마구잡이로 타입을 넣어 보고 any도 넣어 보고 ..ㅋㅋㅋ 어림도 없지. 에러가 계속되다가 팀원 분이 toString() 넣어 보자고 하셔서 해봤더니 바로 떴다!

그러나 이렇게 . . . ㅋㅋㅋㅋㅋ 스타일드 컴포넌트를 만져야 한다.

// 부모 div에 추가

	position: relative;
	overflow: hidden;


// img 태그에 해당하는 자식 요소에는 이렇게

  .pre-img {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

후후 귀엽군 ...
그런데 이렇게 넣은 사진을 삭제하고 싶지 않을까? 그럼 삭제 버튼도 만들어야지 ...

삭제 버튼이 눌리면 input에 있는 요소가 지워져야 한다. 그러니까 버튼에 작용하는 함수로 input을 건드려야 한다는 것! getElement를 사용하는 방법도 있지만 리액트에서 관장하는 방식이 있다. 그게 바로 useRef. useRef를 처음 써 봐서 이렇게 쓰는 거구나! 드디어 알아서 좋았고 신기했다.

const imageRef = useRef<HTMLInputElement>(null);

를 추가하고

<input
      ref={imageRef}
      type="file"
      accept="image/*"
      onChange={handleChangeFile}
/>

여기에 ref를 추가한다.
이 ref를 끌어와 함수에 넣는다. 이렇게!

const handleDeletePreviewFile = (e: React.MouseEvent) 
=> {
    e.preventDefault();
    if (imageRef.current) {
      imageRef.current.value = '';
      setCommunityImage(
        `${import.meta.env.VITE_PUBLIC_URL}/img/default_image3.png`,
      );
    }
  };

button onClick에 함수를 넣어 주기만 하면 ...!

짜잔! 완성! 🤗🤗🤗

profile
Hello, World!

0개의 댓글