Problem
I’m using ReactJS and I’d like to copy some text to the clipboard when a user clicks a link.
I’m using Chrome 52 and don’t have any other browsers to support.
I don’t understand why this code doesn’t copy the info to the clipboard. (The code sample was taken from a Reddit post).
Is it possible that I’m doing something incorrectly? Is there a “proper” approach to do copy to clipboard with reactjs, as far as anyone can tell?
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()
}
Asked by Duke Dougal
Solution #1
If you wish to programatically write data to the clipboard, use this simple inline onClick function on a button.
onClick={() => {navigator.clipboard.writeText(this.state.textToCopy)}}
Answered by Gary Vernon Grubb
Solution #2
Personally, I don’t believe a library is required for this. According to http://caniuse.com/#feat=clipboard, it’s quite generally supported now, but you can still check to see if the capability is available in the current client and just hide the copy button if it isn’t.
import React from 'react';
class CopyExample extends React.Component {
constructor(props) {
super(props);
this.state = { copySuccess: '' }
}
copyToClipboard = (e) => {
this.textArea.select();
document.execCommand('copy');
// This is just personal preference.
// I prefer to not show the whole text area selected.
e.target.focus();
this.setState({ copySuccess: 'Copied!' });
};
render() {
return (
<div>
{
/* Logical shortcut for only displaying the
button if the copy command exists */
document.queryCommandSupported('copy') &&
<div>
<button onClick={this.copyToClipboard}>Copy</button>
{this.state.copySuccess}
</div>
}
<form>
<textarea
ref={(textarea) => this.textArea = textarea}
value='Some text to copy'
/>
</form>
</div>
);
}
}
export default CopyExample;
React 16.7.0-alpha.0 has been updated with React Hooks.
import React, { useRef, useState } from 'react';
export default function CopyExample() {
const [copySuccess, setCopySuccess] = useState('');
const textAreaRef = useRef(null);
function copyToClipboard(e) {
textAreaRef.current.select();
document.execCommand('copy');
// This is just personal preference.
// I prefer to not show the whole text area selected.
e.target.focus();
setCopySuccess('Copied!');
};
return (
<div>
{
/* Logical shortcut for only displaying the
button if the copy command exists */
document.queryCommandSupported('copy') &&
<div>
<button onClick={copyToClipboard}>Copy</button>
{copySuccess}
</div>
}
<form>
<textarea
ref={textAreaRef}
value='Some text to copy'
/>
</form>
</div>
);
}
Answered by Nate
Solution #3
You can do this without using an external library, for example, within a button.
<button
onClick={() => navigator.clipboard.writeText('Copy this text to clipboard')}
>
Copy
</button>
If you’re using Internet Explorer 11 or an earlier browser, you may need to tweak the code slightly. Here’s an example:
<button
onClick={() => window.clipboardData.setData("Text", 'Copy this text to clipboard')}>
Copy
</button>
Hope this helps.
Answered by jerryurenaa
Solution #4
You should probably use a package like the one recommended by @Shubham, however I made a functioning codepen based on what you described: http://codepen.io/dtschust/pen/WGwdVN?editors=1111, http://codepen.io/dtschust/pen/WGwdVN?editors=1111, http://codepen.io It works in Chrome in my browser, so see if there’s something I done there that you missed, or if your application has some added complexity that precludes this from working.
// html
<html>
<body>
<div id="container">
</div>
</body>
</html>
// js
const Hello = React.createClass({
copyToClipboard: () => {
var textField = document.createElement('textarea')
textField.innerText = 'foo bar baz'
document.body.appendChild(textField)
textField.select()
document.execCommand('copy')
textField.remove()
},
render: function () {
return (
<h1 onClick={this.copyToClipboard}>Click to copy some text</h1>
)
}
})
ReactDOM.render(
<Hello/>,
document.getElementById('container'))
Answered by Drew Schuster
Solution #5
The react-copy-to-clipboard npm package is the simplest way.
The command to install it is as follows:
npm install --save react react-copy-to-clipboard
It can be used in the following ways.
const App = React.createClass({
getInitialState() {
return {value: '', copied: false};
},
onChange({target: {value}}) {
this.setState({value, copied: false});
},
onCopy() {
this.setState({copied: true});
},
render() {
return (
<div>
<input value={this.state.value} size={10} onChange={this.onChange} />
<CopyToClipboard text={this.state.value} onCopy={this.onCopy}>
<button>Copy</button>
</CopyToClipboard>
<div>
{this.state.copied ? <span >Copied.</span> : null}
</div>
<br />
<input type="text" />
</div>
);
}
});
ReactDOM.render(<App />, document.getElementById('container'));
The following link contains a full explanation.
Here’s a fiddle that’s on the go.
Answered by Shubham Khatri
Post is based on https://stackoverflow.com/questions/39501289/in-reactjs-how-to-copy-text-to-clipboard