[TIL] 20220815(월)

베르·2022년 8월 15일
0

TIL

목록 보기
15/21
post-thumbnail

📋 주말 ~ 오늘 한 일

- TODAY'S THUMBNAIL 새로운 기능 - 이미지 호스팅, 클립보드

썸네일을 만들 때 마다 파일을 저장해서 쓰기 귀찮아서 URL을 복사해서 쓰고 싶었다
html2canvas로 만든 uri를 이용해 어떻게 할 지 검색을 하다가, 이미지 호스팅 사이트의 api를 사용하여 호스팅 한 후, 그 이미지의 링크를 받아오면 생각한걸 구현할 수 있겠다고 생각했다
결과적으로 원하는 로직을 구현했으나 한 가지 기능을 또 추가하고 싶었다
호스팅 한 URL을 단순히 직접 복사 붙여넣기하여 사용하는 것 보다는, 클릭하면 클립보드에 복사하고 원하는 곳에 붙여넣으면 유저 입장(사실 내 입장)에서 더 편할 것 같았다
이를 구현하는 데엔 크게 세 가지 방법이 있었다

1. document.execCommand('copy')

먼저 Document.execCommand() 메서드를 활용한 복사 방법이 있다

function unsecuredCopyToClipboard(text) {
  const textArea = document.createElement("textarea");
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  try {
    document.execCommand('copy');
  } catch (err) {
    console.error('Unable to copy to clipboard', err);
  }
  document.body.removeChild(textArea);
}

직접 DOM 엘리먼트를 생성하고 그 엘리먼트의 value에 파라미터로 받은 값을 할당한다
그 다음 'copy' 명령어를 통해 선택된 요소를 클립보드에 복사한다
하지만 이 방법은 현재 deprecated 되었다고 한다

2. Clipboard API

Clipboard API는 클립보드 명령(잘라내기, 복사, 붙여넣기)에 응답하거나 시스템 클립보드에 비동기적으로 접근하고 쓸 수 있는 기능을 제공합니다 - MDN

1번의 document.exeCommand()를 대체하기 위해 만들어진 API이다
이 API의 특징은 secured context에서만 사용될 수 있다는 점이다
따라서 https나 이를 지원해주는 브라우저에서만 사용할 수 있다(범위는 공식문서 참고)

function securedCopyToClipboard(content) => {
  if (window.isSecureContext && navigator.clipboard) {
    navigator.clipboard.writeText(content);
  } else {
    unsecuredCopyToClipboard(content);
  }
};

secured context에서만 사용이 가능하기 때문에 먼저 이를 if(window.isSecureContext && navigator.clipboard)로 확인한다
실행되는 환경이 secured context라면 navigator.clipboard.writeText() 메서드를 사용하여 파라미터로 받은 값을 클립보드에 write 한다
navigator.clipboard.readText()를 통해 원하는 위치에 붙여넣기 할 수 있고, 클릭 이벤트 핸들러에 넣어 클릭 시 클립보드에 복사하는 기능을 구현할 수 있다
그리고 secured context가 아니라면 1번에서 구현한 함수를 사용하도록 분기문 처리를 해주었다

3. copy-to-clipboard 라이브러리

이를 조금 더 쉽게 구현하기 위한 방법으로 라이브러리를 활용하는 방법이 있다
바로 copy-to-clipboard 라이브러리이다
사용법도 아주 간단하다

import { CopyToClipboard } from 'react-copy-to-clipboard'

function MyComponent () {
  const hostedUrl = useRecoilValue(hostedUrlState);
  
  return (
        <CopyToClipboard text={hostedUrl} onCopy={() => alert('copied on your clipboard')}>
          <S.HostedUrlContainer>
            <Text text={hostedUrl} fontWeight="bold" fontSize="previewPageH2" color="white"></Text>
          </S.HostedUrlContainer>
        </CopyToClipboard>
  )
}

CopyToClipboard 를 컴포넌트처럼 사용하여 자식 엘리먼트를 클릭했을 때 text 어트리뷰트에 있는 값을 클립보드에 복사한다
onCopy 메서드를 이용해서 copy를 감지하고, copy가 됐을 때 원하는 이벤트를 지정해줄 수 있다
나의 경우엔 alert를 사용하여 클립보드에 복사되었음을 알려주도록 하였다

(글이 너무 길어져 이미지 호스팅은 다음 글에 작성)

- TODAY'S THUMBNAIL 트러블 슈팅

1. 배포 시 clipboard error

내 로컬 환경에서는 위의 방법이 다 정상 작동했다
1+2도 작동을 했고, copy-to-clipboard 라이브러리를 사용해도 원하는 결과가 나왔다
하지만 git pages로 배포를 했을 시 에러가 발생했다

호스팅 된 이미지와 url의 출력까지는 잘 되었으나, 이를 클릭했을 때 해당 에러가 나타났다
클립보드에 복사하는 과정에서 Promise를 리턴하는데 여기서 무언가 문제가 생긴 것 같다
하지만 검색을 해봐도, 주변에 물어봐도 명확한 답을 얻지 못했다
로컬 환경에서는 작동하는 것을 봐선 코드 상의 문제는 아닌 것 같은데 배포 페이지 상에서만 작동되지 않으니 감이 오지 않는다
내일 좀 더 스택 오버플로우 탐방을 해봐야겠다...

2. 완료 클릭 시 느린 로딩 속도

img의 src에 url을 설정하여 해당 이미지를 출력하는 식으로 구현을 했다
하지만 이 속도가 느려도 너무 느리다
원하는 썸네일을 만들고 완료 버튼을 클릭했을 때 2~3초 가량의 시간이 소요됐다
아무래도 imgur로 이미지를 호스팅하고 올리는 시간이 당연히 걸릴거고 완료가 되어야 url이 나오기 때문에 어느정도 예상은 했지만 생각보다 너무 길다
다른 호스팅된 이미지의 링크를 들어가봐도 몇 초가 걸리는 걸로 봐선 내 쪽에서 해결할 수 없는 문제인 것 같다
2~3초 동안 화면이 멈춘다면 나라도 완료 버튼을 다시 누를 것 같은데 이러면 또 다시 이미지를 호스팅하니 시간이 다시 소요된다
결국 유저 입장에선 좋지 않은 경험일 것이다
Suspense를 사용하여 해당 이미지를 불러오기 전까지 스켈레톤처럼 만든 컴포넌트를 보여주는 식으로 처리하려고 했으나 Suspense에 대한 이해도가 부족해서 실패했다
도트한테 물어봐서 방법을 대충 알았으니 내일 좀 더 공부해보고 적용해보면 해결할 수 있을 듯 싶다

🧑‍💻 회고

내 딴엔 단순한 기능을 추가했다고 생각했는데 추가한 기능마다 문제가 생기니 좀 떨떠름하다
그래도 해결할 수 있는 범위 내의 문제여서 다행인 것 같기도 하고...
현업에서는 복잡도 자체가 차원이 다를텐데 기능 추가하기가 정말 쉽지 않을 것 같다고 느꼈다
처음엔 그냥 간단하게 만들어 보려고 했는데 조금씩 욕심이 생겨서 이것저것 기능을 넣어보고 있다
앞으로 추가하고 싶은 기능이 또 몇 개 있는데 그것들까지 적용하면 포트폴리오에 토이 프로젝트로 당당하게 넣을 수 있을 것 같다
아마도..?

0개의 댓글