In reactJS, how to copy text to clipboard?

2020-02-07 14:12发布

I'm using ReactJS and when a user clicks a link I want to copy some text to the clipboard.

I am using Chrome 52 and I do not need to support any other browsers.

I can't see why this code does not result in the data being copied to the clipboard. (the origin of the code snippet is from a Reddit post).

Am I doing this wrong? Can anyone suggest is there a "correct" way to implement copy to clipboard using reactjs?

copyToClipboard = (text) => {
  console.log('text', text)
  var textField = document.createElement('textarea')
  textField.innerText = text
  document.body.appendChild(textField)
  textField.select()
  document.execCommand('copy')
  textField.remove()
}

13条回答
Juvenile、少年°
2楼-- · 2020-02-07 14:40

For those people who are trying to select from the DIV instead of the text field, here is the code. The code is self-explanatory but comment here if you want more information:

     import React from 'react';
     ....

    //set ref to your div
          setRef = (ref) => {
            // debugger; //eslint-disable-line
            this.dialogRef = ref;
          };

          createMarkeup = content => ({
            __html: content,
          });

    //following function select and copy data to the clipboard from the selected Div. 
   //Please note that it is only tested in chrome but compatibility for other browsers can be easily done

          copyDataToClipboard = () => {
            try {
              const range = document.createRange();
              const selection = window.getSelection();
              range.selectNodeContents(this.dialogRef);
              selection.removeAllRanges();
              selection.addRange(range);
              document.execCommand('copy');
              this.showNotification('Macro copied successfully.', 'info');
              this.props.closeMacroWindow();
            } catch (err) {
              // console.log(err); //eslint-disable-line
              //alert('Macro copy failed.');
            }
          };

              render() {
                    return (
                        <div
                          id="macroDiv"
                          ref={(el) => {
                            this.dialogRef = el;
                          }}
                          // className={classes.paper}
                          dangerouslySetInnerHTML={this.createMarkeup(this.props.content)}
                        />
                    );
            }
查看更多
够拽才男人
3楼-- · 2020-02-07 14:40

here is my code:

import React from 'react'

class CopyToClipboard extends React.Component {

  textArea: any

  copyClipBoard = () => {
    this.textArea.select()
    document.execCommand('copy')
  }

  render() {
    return (
      <>
        <input style={{display: 'none'}} value="TEXT TO COPY!!" type="text" ref={(textarea) => this.textArea = textarea}  />
        <div onClick={this.copyClipBoard}>
        CLICK
        </div>
      </>

    )
  }
}

export default CopyToClipboard
查看更多
够拽才男人
4楼-- · 2020-02-07 14:42
import React, { Component } from 'react';

export default class CopyTextOnClick extends Component {
    copyText = () => {
        this.refs.input.select();

        document.execCommand('copy');

        return false;
    }

    render () {
        const { text } = this.state;

        return (
            <button onClick={ this.copyText }>
                { text }

                <input
                    ref="input"
                    type="text"
                    defaultValue={ text }
                    style={{ position: 'fixed', top: '-1000px' }} />
            </button>
        )
    }
}
查看更多
一纸荒年 Trace。
5楼-- · 2020-02-07 14:45

I've taken a very similar approach as some of the above, but made it a little more concrete, I think. Here, a parent component will pass the url (or whatever text you want) as a prop.

import * as React from 'react'

export const CopyButton = ({ url }: any) => {
  const copyToClipboard = () => {
    const textField = document.createElement('textarea');
    textField.innerText = url;
    document.body.appendChild(textField);
    textField.select();
    document.execCommand('copy');
    textField.remove();
  };

  return (
    <button onClick={copyToClipboard}>
      Copy
    </button>
  );
};
查看更多
啃猪蹄的小仙女
6楼-- · 2020-02-07 14:48

If you want to select from the DIV instead of the text field, here is the code. The "code" is the value that has to be copied

import React from 'react'
class CopyToClipboard extends React.Component {

  copyToClipboard(code) {
    var textField = document.createElement('textarea')
    textField.innerText = code
    document.body.appendChild(textField)
    textField.select()
    document.execCommand('copy')
    textField.remove()
  }
  render() {
    return (
      <div onClick={this.copyToClipboard.bind(this, code)}>
        {code}
      </div>

    )
  }
}

export default CopyToClipboard
查看更多
forever°为你锁心
7楼-- · 2020-02-07 14:52

Here's another use case, if you would like to copy the current url to your clipboard:

Define a method

const copyToClipboard = e => {
  navigator.clipboard.writeText(window.location.toString())
}

Call that method

<button copyToClipboard={shareLink}>
   Click to copy current url to clipboard
</button>
查看更多
登录 后发表回答