11/24 이미지 받아오기

김하은·2022년 11월 24일

오늘은 useRef와 그것을 이용한 이미지를 받아오는 방법을 해보았다.

보통 브라우저에서 해당사이트의 정보들을 받아오는 과정중에서 가장 나중에 불러와지는것이 바로 이미지 부분이다.

이미지는 img src부분의 위치에 가서 받아오는 것인데, 이 src에는 사진전용컴퓨터? 라고도 할 수 있는 곳의 주소가 들어간다고 보면된다.
그곳까지 가서 받아오니 느리게 받아오는 것이다.

그럼 왜 따로 저장할까?
바로 용량문제때문이다.

일단 DB에 표 형식으로 저장된다고 보면 이미지는 BLOB이라는 타입으로 저장되게된다.
바이너리 라지 오브젝트의 준말인데,

왜 라지 라는 말이 붙었나?

사진을 확대하다보면 어느순간 사진이 깨져서 작은사각형형태로 보이게 된다. 이 각각의 하나하나에 rgb색상코드가 들어가고 그것은 0~255까지의 숫자로 표현된다. 그것이 수백, 수천개 모인것이 사진이고, 결국 이 전체는 숫자로 표현이 가능한데, 그만큼 용량을 많이 차지한다는 말이다.이것을 텍스트형태로 바꾸면 어마어마한 용량이 될 수도 있다.
영상또한 여러 사진들의 집합으로 볼 수 있기에 마찬가지의 결과를 가져온다.

그렇기에!
DB에 직접적으로 저장하지 않고, 사진전용? 컴퓨터에 저장을 해 그 주소로가서 다운받아오는 식으로 사용한다.
이것을 서비스로 제공하는 회사를 이용하면 된다.

아마존웹서비스:aws,
구글클라우드플랫폼:gcp,
마이크로소프트:azure
가 있다.

저 회사들을 클라우드 서비스를 제공하는 클라우더 프로바이더라고 한다.

현재 트랜드는 클라우드제공업체를 이용하는것이라고한다.

이미지업로드버튼만들기!

input태그의 type="file"을 사용하면 자동으로 클릭하는 버튼을 누르고 그 버튼을 클릭하게되면 내컴퓨터의 파일이 열려 그중에서 선택이 가능하다.
업로드 버튼을 클릭 ==> uploadfile로 mutation을 날림,게시물등록으로 createBoard로 API를 날리기 ===>
벡엔드로. 벡엔드에선 이미지 파일을 숫자나 텍스트로 바꿔 클라우드에 저장, 클라우드에서는 그 주소를 반환,createBoard를 받아 게시판생성 ====>DB에 테이블로 저장되면 imgurl부분에 해당클라우드에서 받아온 주소가 들어감.

클라우드에서 받아온 주소가 image의 src부분에 들어가는 것.

onChange부분에는 선택한 파일 이름이 들어가게된다.

업로드단계부터가 mutation을 날려주는 부분이다.

useMutation<여기는 결과타입, 여기는 variables의 타입>

이미지 뮤테이션을 날리기 전에 꼭 해야하는 과정이 있다.
포트폴리오용에는 같이 해놨으나 과제용폴더에는 깜빡잊어 곤혹을치렀다...
바로 아폴로 업로드클라이언트를 따로 설치하고, 그것에관해 세팅까지 해줘야 한다는 것이다.

yarn add apollo-upload-client

그리고 이것에 관한 타입스크립트도 존재하니 같이 설치 해준다.

yarn add @types/apollo-upload-client --dev

아폴로 세팅은 일전에 따로 컴포넌트를 분리해놨었다.
components ==> commons ==>apollo에 들어가 세팅을 마무리해준다.

import { createUploadLink } from "apollo-upload-client";

apollo-upload-client에서 createUploadLink를 import 하고,
createUploadLink를 번수에담아 본래의 client에 있던 uri를 옮기고 그 uri를 link라는것으로 받는데

link: ApolloLink.from([uploadLink]),

ApolloLink라는 것은 아폴로 클라이언트에서 임폴트 해오고, from에 link로 연결해주는 것을 배열로 받기에 대괄호안에 createUploadLink를 담은 변수를 넣어주면된다. 현재는 연결할것이 하나뿐이기에 하나만 들어간다.

이 설정을 해주지 않으면,, 쿼리문을 작성했다고 하더라도

이렇게..url을 가져오지 못하는것을 볼 수 있다.

한참헤매다가 블로깅하면서 정리하다가 깨달았다...
진짜 왜이럴까..

연결을 다해주고 img태그로 화면에 그려주는데 , src의 앞쪽에는 클라우드 스토리지주소가 들어가야한다.
띄어쓰기, 스펠링 주의.


input type="file" 에 관해 더 알아보니 브라우저별로 나타나는 모양이 다르다는것을 알았다.
그런데 이 UI는 수정할 수 없다.
수정을하려면 이 태그를 눈에서 안보이게하고 useRef를 사용해 연결하면 되는데, (for속성을 사용하는 방법도 있는것 같다) ref는 레퍼런스라는 말로 참조한다는 의미, 변수에 태그를 담을 수 있게 해준다.

const qqq = useRef()

이렇게 하고 담을 태그안에 ref{qqq} 이런식으로 적어주면 그 태그를 qqq라는 변수에 담을 수 있다.
qqq.click()하면 그 태그가 클릭되고, qqq.change()하면 그 태그를 onchange할 수 있다.

*ref={qqq}에 빨간줄이 뜨는 이유 ==> 초기값문제
==> const qqq = useRef() 여기 소괄호를 아무것도 안넣지 말고 null을 넣음.
즉, const qqq = useRef(null)로
실제 실무에서는 저 변수 이름을 뒤에 Ref를 붙여 사용한다.
가짜버튼으로 할 태그와 연결하기
태그는 버튼이든, 이미지든 상관없음.
input테그를 가정하고
const onClickImg = () =>{
qqq.current?.click() ===> 현재있는 qqq가 있으면 클릭해줘.(옵셔널 체이닝 ?. 사용하지 않으면 빨간줄생김)
}

이미지 검증하기:
image vaildation이라고함.
mutation보내기전 즉, try문 전에 검증을 해야한다.
if 문을 사용해 file의 size가 없으면, 아래문 실행안함, 용량이 어느정도인지 제한등..

if 문으로 type.includes("jpg")이런식으로 막아주는 등을 할 수 있지만, 진짜버튼 즉 input type ="file" 에 accept라는 것을 주는 방식으로도 막아줄 수 있다.
accept에 적어줄경우 해당 확장자를 제외하고는 선택하지못하게 나오게된다. if문으로는 해당확장자가 아니면 알림창이뜨게 해줄 수 있다.
accept="image/jpg,..." 이렇게 쉼표로 구분해 사용하고, image/로도 쓰는것 같다.
그리고
.* ? 모든 파일을 선택할수도 있다고 한다.

상황에따라 다르게 사용하자.

이 검증부분도 import 로 따로떼어 사용할 수 있다.
commons의 라이브러리로빼서 함수로 작성한뒤 import 로 받아오고 return 부분은 원래 있던 컴포넌트의 try문실행을 막아주는것이니 함수안에 넣어준 if문의 조건들이 아니라면 return true 로 바꾸고 if 문의 조건에 맞는다면 return false를 하여 만든함수를 본문에 검증하는 부분에 (아까와 같은곳)넣고 변수에 담아 만약 받은 함수가 flase라면 return 해주는 식으로 작성한다.
변수명 === false 는 !변수명 으로 간단히 표현할 수 있다.

정리:
DB에는 url이 들어가고, 실제 파일은 스토리지(클라우드)에 들어간다! 따라서 조회해보면 url만 받아볼 수 있다.


용량계산
키로바이트 -> 메가바이트 -> 기가바이트...
1024 이다.
5MB를 기준으로 한다면 5
1024 하면 5KB, 거기에 또 *1024를 한다면 5MB가 된다.

참고자료를 받았는데 아직 훑어보기만했다. 다시 정리해가며 봐야겠다.

참조:https://helloinyong.tistory.com/275

0개의 댓글