Skip to content

Instantly share code, notes, and snippets.

@robotzhang
Created January 16, 2020 11:45
Show Gist options
  • Save robotzhang/27cee57d90451e914c3b3e4fb2f07639 to your computer and use it in GitHub Desktop.
Save robotzhang/27cee57d90451e914c3b3e4fb2f07639 to your computer and use it in GitHub Desktop.
clipboard.js 兼容性很好,可惜整个实现和使用的逻辑是基于 DOM 的,在 React 中不是很好用,React 16.8 推出了 hook 之后使得这个事情变得极其简单了。
import {
useRef, useLayoutEffect, useCallback, useState,
} from 'react';
import Clipboard from 'clipboard';
/**
* 复制到粘贴板
* @usage
* const clipboard = useClipboard({
* copiedTimeout: 1000,
* });
* <button
* type="button"
* ref={clipboard.buttonRef} // 必须指定 buttonRef
* data-clipboard-text={receiptUrl} // 如果不是从 input or textare 中复制则需要指定这个属性
* className="btn btn-outline-secondary btn-sm"
* >
* {clipboard.copied ? '已复制' : '复制'}
* </button>
* */
const useClipboard = ({ onSuccess, onError, copiedTimeout = 1000 }) => {
const buttonRef = useRef(null);
const [copied, setCopied] = useState(false);
// 复制完成的内部处理
const onCopySuccess = useCallback(() => {
setCopied(true);
setTimeout(() => {
setCopied(false);
}, copiedTimeout);
}, []);
// 复制
function clipboardCopy() {
const cb = new Clipboard(buttonRef.current);
cb.on('success', (e) => {
if (onSuccess) onSuccess(e);
onCopySuccess();
});
cb.on('error', (e) => {
if (onError) onError(e);
});
return cb;
}
//
useLayoutEffect(() => {
let cb = null;
if (buttonRef.current) {
cb = clipboardCopy();
}
return () => {
if (cb) cb.destroy();
};
});
//
return { copied, buttonRef };
};
export default useClipboard;
export { useClipboard };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment