회원가입 시, 이메일, 이름, 비밀번호 뿐만 아니라 사용자의 프로필 이미지도 함께 서버에 보내주기 위해 이미지 업로드란을 만들어주었어요. 파일 선택에서 컴퓨터에 있는 이미지를 선택하면 프로필 이미지란에서 사용자가 선택한 이미지를 미리 볼 수 있죠.
<input type="file" />
input의 default 타입은 text
죠. 이 타입을 file
로 변경해주면 컴퓨터에 있는 파일을 선택해 업로드할 수 있어요.
<input>
과 <label>
그런데 파일 선택 버튼이 마음에 들지 않아요. 이 때, 제가 찾은 방법은 label
태그를 활용하는 것이었어요. input
태그는 display:none
으로 숨겨주었고, label
에 스타일을 주었어요.
input
태그는 label
태그와 함께 쓰여 input
에 대한 보충 설명을 해줍니다. label
의 for
속성과 input
의 id
속성에 같은 값을 입력해 이 두 태그를 연결했어요. JSX에선 label
의 for
을 htmlFor
로 작성해줘야 한다는 점-!
<form>
<label className="signup-profileImg-label" htmlFor="profileImg">프로필 이미지 추가</label>
<input
className="signup-profileImg-input"
type="file"
accept="image/*"
id="profileImg"
/>
</form>
🖐🏻 잠깐! input의 accept속성
input
태그의 accept 속성은 서버로 업로드 할 수 있는 파일의 타입을 명시해요.- 이 속성은
input
type이file
인 경우에만 사용할 수 있어요.image/*
은 모든 타입의 이미지 파일이 허용됨을 의미합니다.
// label태그
.signup-profileImg-label {
margin: 5px 0 20px 0;
font-weight: bold;
font-size: 13px;
color: #0095f6;
display: inline-block;
cursor: pointer;
}
// input태그
.form-signup input[type="file"] {
display: none;
}
이미지를 업로드하면 동그란 원 안에 아래처럼 업로드한 이미지로 변경시키고자 했어요.
const [imgFile, setImgFile] = useState("");
const imgRef = useRef();
// 이미지 업로드 input의 onChange
const saveImgFile = () => {
const file = imgRef.current.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
setImgFile(reader.result);
};
};
// 업로드 된 이미지 미리보기
<img
src={imgFile ? imgFile :`/images/icon/user.png`}
alt="프로필 이미지"
/>
// 이미지 업로드 input
<input
type="file"
accept="image/*"
id="profileImg"
onChange={saveImgFile}
ref={imgRef}
/>
FileReader API
이미지 미리보기를 구현하기 위해 FileReader API
를 사용했어요. FileReader
는 웹 API랍니다. 웹 API란 개발자가 브라우저 상에 쉽게 개발할 수 있도록 도와주는 객체의 모음들이죠. 이 FileReader
도 객체의 형태를 띄고있어요. 따라서 new FileReader()
로 파일리더를 만들어준 뒤 사용해줄 수 있어요.
readAsDataURL
readAsDataURL
을 통해 파일을 URL로 만들 수 있어요. 파일 정보를 주소처럼 사용할 수 있게 된답니다.