
파일 업로드 버튼을 만드는 도중에, 상단의 이미지와 같이 디자인을 넣고 싶었다.
하지만 input 태그는 저런 느낌으로 꾸며줄 수가 없었고...
여러가지 방법을 생각해냈지만 순수 자바스크립트 문법으로는 전부 실패해버렸다.
그러다 마지막에 떠오른게 이 친구였다.
바로 useRef()! useRef를 통해 div가 브로커 행세를 할 수 있게 된다.
해결법은 간단했다.
1. 이미지 업로드용 <input type="file">에 useRef()를 걸어주고 { display: none } 처리한다.
2. 그 후 <ImageStandBy> 에서 onClick 이벤트가 발생할 때 useRef()를 통해 <input>이 실행되게 만든 후,
3. <input type="file">의 onChange 이벤트에서 setter 함수를 실행하여 state를 변경할 수 있도록 해주면 된다!
뭔 개소린지 모르겠다면 코드를 봐보도록 하자!
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]),
});
};
<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>
위 코드는
조건부 렌더링을 통해 ? (이미지 업로드 버튼을 출력하거나) : (업로드된 이미지를 보여주는)
코드이다.
스타일드 컴포넌트를 이용했기에 태그가 보이지 않는 점은 양해 바란다.