오늘은 이미지가 프로세스에 대한 전박적인 것들을 배우고 직접 올려보았다.
이미지를 그저 삽입하는 거 밖에 할 줄 몰랐고 업로드도 비슷하게 간단한 원리 일 줄 알았는데 생각보다는 복잡한 (?) 구조였다.
올려서 불러오기 이전에 데이터를 안전하게 저장,활용하기 위해 스토리지(클라우드 서비스)에 대한 이해가 필요했고 이미지를 저장하면 url 로 DB에 저장되고 보이는 원리였다.
이미지 파일을 input 태그에 넣을 때 확장자를 검증하는 방법은 크게 2가지가 있다.
첫 번째 방법은 input 태그에 accept속성을 이용하는 것이
두 번째 방법은 onChange 함수 안에서 type을 비교하는 것이다.
▶︎ input 태그에 accept 속성 활용하여 확장자 검증하기
accept 속성에 원하는 확장자만 선택 되게 하는 방법
<div>
<img style={{ width: '500px' }} id="image" />
<input type="file" **accept="image/png"** onChange={readImage}></input>
</div>
▶︎ onChange 함수 안에서 type을 이용하여 검증하기
input 태그에 파일을 넣으면 해당 파일의 정보를 target.files[0]으로 알 수 있다.
console.log()로 어떤 정보가 있는지 확인해보고
if문을 이용해서 확장자를 지정한다.
export default function Web() {
const readImage = (input) => {
// 인풋 태그에 파일이 있는 경우
if (input.target.files && input.target.files[0]) {
//png일 경우에만 코드 실행
if (input.target.files[0].type !== 'image/png') {
alert('png만 가능합니다.');
} else {
// FileReader 인스턴스 생성
const reader = new FileReader();
// reader가 이미지 읽도록 하기
reader.readAsDataURL(input.target.files[0]);
// 이미지가 로드가 된 경우
reader.onload = (e) => {
const previewImage = document.getElementById('image');
previewImage.src = e.target.result;
};
}
}
};
return (
<>
<div>
<img style={{ width: '500px' }} id="image" />
<input type="file" onChange={readImage}></input>
</div>
</>
);
}
우리는 이미지 용량도 제한할 수 있습니다. 너무 큰 파일을 올리면 부담스럽기 때문에 위에서 배운 target.files[0]을 이용해 파일 정보를 확인 할 수 있다.
하지만 "123494"가 어떤 파일 크기를 얘기하는지는 알기 힘들다.
위에 나온 사이즈를 알기 쉽게 비교하는 방법은 1 1024 1024 를 이용하자!
1 1024 1024 는 1MB입니다.
5 1024 1024 는 5MB죠.
또한 if문 추가해서 사이즈 제한을 걸자!
const readImage = (input) => {
// 인풋 태그에 파일이 있는 경우
if (input.target.files && input.target.files[0]) {
**const fileSize = 5 * 1024 * 1024;
if (input.target.files[0].size > fileSize) {
alert('5MB이하만 가능합니다 .');**
} else {
// FileReader 인스턴스 생성
const reader = new FileReader();
// reader가 이미지 읽도록 하기
reader.readAsDataURL(input.target.files[0]);
// 이미지가 로드가 된 경우
reader.onload = (e) => {
const previewImage = document.getElementById('image');
previewImage.src = e.target.result;
};
}
}
};
https://www.npmjs.com/package/apollo-upload-client 에서 제공하는 apollo-upload-client 설치하고 TypeScript
를 사용한다면 yarn add @types/apollo-upload-client
까지 해준다.
그리고 ApolloClient 가 이미지 업로드 까지 허용 하게 하려면 설정을 따로 해줘야하는데
제일 먼저 설치한 createUploadLink 를 import 해주고 기존에 API를 받아오는 주소를
createUploadLink에 다시 입력해서 ApolloClient가 했던 역할을 수행함과 동시에 업로드 파일기능도 같이 하게 된다.
스토리지를 이용해서 이미지를 불러오려면
img
태그에src
를 불러올때 스토리지 이미지 시작 주소를 꼭 입력 해야한다.
실무에서는 input파일 버튼을 숨기고
(display: "none")
UI나 Img로 버튼을 대체한다.
useRef
를 이용해서 UI 를 선택 해도 인풋이 강제로 실행 시키게 한다.
onClick
함수를 만들어서 UI를 누르면ref
가있는 인풋이 실행되게 한다.