[react] div를 input태그로 만들기 (feat. useRef())

AM_I_TRASH·2022년 8월 7일

제작물

목록 보기
1/6

Prologue

파일 업로드 버튼을 만드는 도중에, 상단의 이미지와 같이 디자인을 넣고 싶었다.
하지만 input 태그는 저런 느낌으로 꾸며줄 수가 없었고...
여러가지 방법을 생각해냈지만 순수 자바스크립트 문법으로는 전부 실패해버렸다.
그러다 마지막에 떠오른게 이 친구였다.

What?

바로 useRef()! useRef를 통해 div가 브로커 행세를 할 수 있게 된다.

How?

해결법은 간단했다.
1. 이미지 업로드용 <input type="file">에 useRef()를 걸어주고 { display: none } 처리한다.
2. 그 후 <ImageStandBy> 에서 onClick 이벤트가 발생할 때 useRef()를 통해 <input>이 실행되게 만든 후,
3. <input type="file">의 onChange 이벤트에서 setter 함수를 실행하여 state를 변경할 수 있도록 해주면 된다!

뭔 개소린지 모르겠다면 코드를 봐보도록 하자!

사용한 hooks와 function들

const [imageInfo, setImageInfo] = useState({
   file: null,
   previewURL: '',
 });
const photoInput = useRef();

const imageUploadOnClick = e => {
   e.preventDefault();
   photoInput.current.click();
 };

const imageInputOnChange = e => {
 setImageInfo({
   file: e.target.files[0],
   previewURL: URL.createObjectURL(e.target.files[0]),
 });
};

HTML 코드

<ImageUploadContainer>								// div
  {imageInfo.file === null ? (
    <ImageStandBy onClick={imageUploadOnClick}>		// div or button
      <AiFillCamera />								// react-icons 아이콘
      <p>사진 올리기</p>
      <p>(* 최대 10장까지)</p>
    </ImageStandBy>
  ) : (
      <img
        src={imageInfo.previewURL}
        alt="previewImage"
        ref={imageOverlay}
        onClick={imageOverlayOnClick}
      />
  )}
  <input
    type="file"
    accept="image/jpg, image/jpeg, image/png"
    multiple
    ref={photoInput}
    onChange={imageInputOnChange}
    style={{ display: 'none' }}
  />
</ImageUploadContainer>

위 코드는
   조건부 렌더링을 통해 ? (이미지 업로드 버튼을 출력하거나) : (업로드된 이미지를 보여주는)
코드이다.
스타일드 컴포넌트를 이용했기에 태그가 보이지 않는 점은 양해 바란다.

profile
짝퉁 프로그래머

0개의 댓글