개발 | 코딩

URL 링크 클립보드에 복사하기 기능 만드는 법 | 리액트 링크 복사하기

fire2025 2021. 2. 26. 19:16

리액트에서 URL 링크를 클립보드에 복사하는 기능을 구현해 보았다. 현재 페이지의 웹사이트 주소를 복사하고 다른 앱이나 브라우저에서 붙여넣기할 수 있도록 만든 기능이다. 

이 기능을 만드는 방법은 여러가지이다. 하지만 이 블로그에서 만드는 방법을 핵심만 요약하면, 아래와 같다.

1. 현재 페이지의 url 주소를 <TextArea> 라는 html 태그에 담아둔다.

2. document.execCommand 기능으로 url 주소를 복사한다.

3. 복사하는 내용이 담긴 <TextArea> 태그가 사용자에게 보이지 않도록 처리한다.

자세한 방법과 코드는 아래에 설명되어 있다.


1. 준비 과정: 어떤 버튼을 누르면 링크 복사하기 메뉴가 떠야하는지 파악한다.

이 스크린샷은 인스타그램 예시 사진이다.

1번이라고 쓰여져있는 상단 우측 버튼을 누르면, 화면 하단에서 팝업 메뉴가 뜬다. 

그 중 우리는 '2'라고 표시된 '링크 복사' 버튼을 눌렀을 때의 기능을 구현할 것이다.

인스타그램 링크 복사 이미지 예시

2. 준비 과정: 아이콘 디자인을 준비한다.

인스타그램 예시는 아이콘이 필요없는 경우이지만, 여러 앱으로 공유하는 옵션을 주는 경우에는 아이콘이 필요하다.

아래 그림처럼 링크 복사하기 버튼의 아이콘을 준비한다.

트위터 공유하기 버튼 아이콘 예시

나는 아래와 같은 팝업 버튼에서 링크복사 버튼을 구현하게 되었다.

공유하기 팝업 이미지 예시

예시 코드 1

/* Styled Component 스타일 컴포넌트 */
const StyledButton = styled.div`
  border-radius: 24px;
  border: 1px solid #ECECF5;
`
const Caption = styled.div`
  display: flex;
  justify-content: center;
  width: 100%;
  font-size: 12px;
  margin-top: 8px;
`

/* 본 페이지의 렌더링 파트 중 링크 복사 부분*/
<div>
/* 카카오톡 버튼 */
</div>
<div>
  <StyledButton> 
    <ButtonItem type={ButtonType.SHARE_COPY_URL} onClick={copyUrl} />
    /* ButtonItem 은 내부적으로 구현한 Button 컴포넌트 */
    /* 버튼을 클릭하면 copyUrl 함수가 실행된다 */
    /* 코드 추가 예정 */
   </StyledButton>
  <Caption>링크복사</Caption>
</div>

3. Html 태그 <textarea>, React useRef hook 을 사용한다.

1. textarea 태그는 장문의 텍스트를 기록하는 용도로 보통 사용된다.

  • 이 예제에서는 현재 페이지의 url 을 저장하기 위해 사용했다.
  • textarea 의 value 속성에 현재 웹사이트 주소값을 입력한다. window.location.href 값이 곧 현재 url 주소이다.

 

2. React에서 DOM 노드에 직접 접근하기 위해서 useRef 훅을 사용했다. 

출처: https://developer.mozilla.org/ko/docs/Web/HTML/Element/textarea

예시 코드 2

/* Styled Component */
/* 위의 내용은 생략 */
const TextArea = styled.textarea`
  // 추후 기재
`

// 참고로 이 코드는 함수형 컴포넌트로 만들고 있는 예시이다.
// useRef 훅으로 copyUrlRef 를 생성하고
// 아래 렌더링 부분의 textarea 태그에 copyUrlRef를 입력한다.
const copyUrlRef = React.useRef()

/* 본 페이지의 렌더링 파트 중 링크 복사 부분*/
<div>
/* 카카오톡 버튼 */
</div>
<div>
  <StyledButton> 
    <ButtonItem type={ButtonType.SHARE_COPY_URL} onClick={copyUrl} />
    /* ButtonItem 은 내부적으로 구현한 Button 컴포넌트 */
    /* 버튼을 클릭하면 copyUrl 함수가 실행된다 */
    <form>
      <TextArea
      ref={copyUrlRef}
      value={window.location.href}
      />
    </form>
   </StyledButton>
  <Caption>링크복사</Caption>
</div>

4. 링크복사 버튼을 클릭하면 실행되는 함수 로직을 구현한다.

onClick 을 하면 copyUrl 함수를 실행해야 한다. 이 copyUrl 함수 안에서 우리는 ref, url 주소 등을 사용해서 링크를 복사하는 기능을 만든다.

  • 우선 브라우저에서 copy 명령어가 지원되는지 확인한다. 지원되지 않는 브라우저라면 알림창을 띄운다.
  • useRef 가 반환하는 객체는 current 라는 속성을 가지고 있다. textarea 컴포넌트가 제대로 로드 되었다면, copyUrlRef.current 속성이 잘 반환된다.
  • 우리는 ref 를 TextArea 컴포넌트에 주었으니, `copyUrlRef.current.select()` 를 실행하면, TextArea 컴포넌트가 가진 value 값을 받게 된다.
  • document.execCommand 에는 여려 명령어가 있다. 우리가 키보드로 ctrl+c , ctrl+v 하는 것과 같다. 주로 블로그 에디터를 개발할 때 자주 쓰게 되는 기능이다. 
  • 마지막으로, 링크 복사가 성공적으로 완료되면, 약 200 밀리초 이후에 링크가 복사되었다는 토스트 알림창을 띄우고 싶었다. 

예시 코드 3

 

// url 복사하는 함수
const copyUrl = (e) => {
  if (!document.queryCommandSupported("copy")) {
  	return alert("복사 기능이 지원되지 않는 브라우저입니다.");
  }

  copyUrlRef.current.select();
  document.execCommand('copy');
  e.target.focus();

 // 링크가 복사되었어요! 라는 토스트 알림창을 띄우고 싶은 경우
 // openToast 라는 함수가 구현되어 있다는 가정.
  setTimeout(() => {
    openToast(), 200)
}

 

5. <form><textarea> 영역이 화면에 보이지 않도록 처리한다.

마지막으로 css 처리해야 할 것이 남아있다.

form, textarea 태그를 그대로 쓰면 첨부한 이미지처럼 텍스트박스가 그대로 노출된다. 최대한 화면에서 보이지 않게 처리해보자.

textarea 가 보이는 예시

  • StyledButton 가 부모 컴포넌트, textarea 가 자식 컴포넌트이다. 
  • StyledButton 의 기본 높이와 너비 값을 벗어나는 엘리먼트가 보이지 않도록 overflow: hidden 을 추가한다. 
  • TextArea 컴포넌트를 바닥 어딘가에 위치시켜서 최대한 보이지 않게 처리하고 싶다. 자식 컴포넌트에 position: absolute 를 적용하기 위해서, 부모 컴포넌트인 StyledButton에 position: relative 속성을 추가한다.
  • TextArea 컴포넌트에 position: absolute 를 적용하고, left:0, bottom: 0 으로 최하단 왼쪽에 위치시킨다. width, height, opacity 값 모두 0 으로 준다.

예시 코드 4

/* Styled Component 스타일 컴포넌트 */
const StyledButton = styled.div`
  position: relative;     // url 복사할때, textarea 영역이 보이지 않도록 하기 위해.
  overflow: hidden;
  width: 64px;
  height: 64px;
  border-radius: 24px;
  border: 1px solid #ECECF5;
`
// 
const TextArea = styled.textarea`
  position: absolute;
  width: 0px;
  height: 0px;
  bottom: 0;
  left: 0;
  opacity: 0;
`

// render, return
<div>
  <StyledButton>
    <ButtonItem type={ButtonType.SHARE_COPY_URL} onClick={copyUrl} />
      <form>
        <TextArea
        ref={copyUrlRef}
        value={window.location.href}
        />
      </form>
  </StyledButton>
  <Caption>링크복사</Caption>
</div>

최종 코드

const Menu = ({ 

  const copyUrlRef = React.useRef()
  
  // 공유하기 버튼 클릭하면 뜨는 팝업
  // 인스타그램의 경우, ... 버튼을 클릭했을 때 뜨는 메뉴 팝업.
  // 팝업의 body 부분이 <ShareButtons /> 컴포넌트이다.
  const onClickShare = () => {
    const payload = {
      ...,
      description: () => <ShareButtons />
    }
    runPopup(payload)
    // runPopup 함수는 다른 곳에 구현되어있다.
  }

  const ShareButtons = () => {
    return (
      <Wrapper>
        <FlexDiv>
          // 카카오톡 버튼
        </FlexDiv>
        <FlexDiv>
          <StyledButton>
            <ButtonItem type={ButtonType.SHARE_COPY_URL} onClick={copyUrl} />
            <form>
              <TextArea
                ref={copyUrlRef}
                value={window.location.href}
              />
            </form>
          </StyledButton>
          <Caption>링크복사</Caption>
        </FlexDiv>
      </Wrapper>
    )}
  
  // Menu 함수형 컴포넌트의 return 렌더링 파트
  return(
     <MenuBar>
     	<ButtonItem type={ButtonType.SHARE} onClick={onClickShare} />
		// 기타 버튼 컴포넌트
     </MenuBar>
  )
 })

참고한 웹사이트 링크입니다.

velog.io/@edbera/React-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90-%EB%A0%8C%EB%8D%94%EB%90%9C-%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%A5%BC-%ED%81%B4%EB%A6%BD%EB%B3%B4%EB%93%9C%EC%97%90-%EB%B3%B5%EC%82%AC%ED%95%98%EA%B8%B0

 

React 컴포넌트에 렌더된 텍스트를 클립보드에 복사하기

안된다.. 보통 안된다. 리액트 어드민 프로젝트를 진행중에텍스트를 클립보드에 복사해 줘야할 상황이 생겼다.정확하게는 두개의 컴포넌트에 나누어 렌더되어있는 텍스트를 클립보드에 복사하

velog.io

coderrocketfuel.com/article/how-to-copy-text-to-the-clipboard-in-react-js

 

How to Copy Text to The Clipboard in ReactJS

A guide on how to copy a textarea's value to the clipboard in a React.js application.

coderrocketfuel.com

kyounghwan01.github.io/blog/React/clipboard-copy/#%EC%84%9C%EB%A1%A0

 

클립보드 텍스트 복사하기

클립보드 텍스트 복사하기, react, queryCommandSupported, javascript, react16, react hook, 리엑트, 프론트엔드, 웹, web, javascript copy to clipboard

kyounghwan01.github.io

stackoverflow.com/questions/50644602/how-to-share-current-url-in-reactjs

 

How to share current URL in ReactJS

I want to give the user the ability to click a button that will copy the current URL to the clipboard. Since I use react-router all I need is extract the this.props.history.location.pathname and ap...

stackoverflow.com

www.daleseo.com/react-refs/

 

[React] ref로 HTML 엘리먼트에 접근/제어하기

Engineering Blog by Dale Seo

www.daleseo.com

ko.reactjs.org/docs/hooks-reference.html

 

Hooks API Reference – React

A JavaScript library for building user interfaces

ko.reactjs.org