위코드 1차 팀프로젝트를 진행하며 정리한 내용입니다.
회원가입 시 프로필 사진을 입력하는 기능을 구현했습니다. input 태그로 파일을 입력받는 동시에 해당 사진을 상위 요소에 그려주기 때문에 입력 후 리렌딩이 되지 않도록 useRef 훅을 사용했습니다.
우선 useRef() 를 선언하고
const imgRef = useRef();]
jsx 는 아래와 같이 작성했습니다. 부모 요소인 label 의 htmlFor 에 자식요소 Input 태그의 id 값을 넣어 두 요소를 연결했고(부모요소가 input 태그 이벤트를 받도록) input 태그의 type 을 file 로 해 이미지를 전송받고 해당 버튼은 css 로 지웠습니다. input 태그로 입력되는 값의 ref 속석에 useRef 로 만든 변수를 담습니다.
<label className="imgBoxLabel" htmlFor="profileImg">
{imageUrl ? (
<img className="labelImg" src={imageUrl} alt="uploadImg" />
) : null}
<div className="imgUploadBtn">
<i className="fa-sharp fa-solid fa-camera" />
</div>
<input
id="profileImg"
className="profileImgInput"
type="file"
name="imageUrl"
ref={imgRef}
onChange={onChangeImage}
/>
</label>
onChangeImage 함수는 아래와 같습니다. FileReader 를 사용해 imgRef 값안의 값을 선택하고 readAsDataURL 로 url로 변경한 후 미리 만들어 둔 imgeUrl 스테이트에 해당 값을 저장합니다.
const imgRef = useRef();
const onChangeImage = () => {
const reader = new FileReader();
const file = imgRef.current.files[0];
reader.readAsDataURL(file);
reader.onloadend = () => {
setImageUrl(reader.result);
};
};
위 코드의 imgRef 을 순서대로 콘솔을 찍어보면 아래와 같습니다.
그 외에 스타일링 코드로, 넣어주는 이미지는 비율을 맞추기 위해 object-fit: cover; 를 사용했습니다.
.labelImg {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
}