首页 > 解决方案 > 使用 useRef 挂钩将副本复制到剪贴板

问题描述

我正在尝试使用 useRef 钩子在 React 中处理复制到剪贴板。在没有任何额外库的情况下如何实现它?这是我的代码,但它引发错误“myRef.current.select 不是函数”。

import React, { useRef } from "react";

const Element = () => {
  const myRef = useRef();

  const copyToClipboard = () => {
    myRef.current.select();
    document.execCommand("copy");
  };

  return (
    <div>
      <span onClick={copyToClipboard} ref={myRef}>
        Text to be copied
      </span>
    </div>
  );
};

export default Element;

标签: javascriptreactjsreact-hooksclipboard

解决方案


运行以下代码段。

  1. 有一个单独的CopyToClipElement组件(使用 React Hooks)来处理给定文本道具的副本。在你的渲染中使用这个组件。

const CopyToClipElement = ({ text }) => {
  const myRef = React.useRef(null);
  const [data, setData] = React.useState(text);
  React.useEffect(() => setData(text), [text]);

  React.useEffect(() => {
    if (myRef.current && data) {
      myRef.current.select();
      document.execCommand("copy");
      setData(null);
    }
  }, [data, myRef.current]);

  return <div>{data && <textarea ref={myRef}>{data}</textarea>}</div>;
};

const Element = () => {
  const [copyText, setCopyText] = React.useState("");
  const data = ["Text to be copied", "Copy foo"];

  return (
    <div>
      {data.map((text) => (
        <span
          style={{ margin: "10px", cursor: "pointer", color: 'blue' }}
          onClick={() => setCopyText(text)}
        >
          {text}
        </span>
      ))}
      <CopyToClipElement text={copyText} />
    </div>
  );
};

const domContainer = document.querySelector('#app');
ReactDOM.render(<Element/>, domContainer);
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="app"> </div>

  1. 或者,只需copyToClipboard在纯 JS 中添加实用程序方法。

const copyToClipboard = (text: string) => {
  const ta = document.createElement("textarea");
  ta.innerText = text;
  document.body.appendChild(ta);
  ta.select();
  document.execCommand("copy");
  ta.remove();
};

const Element = () => {
  const data = ["Text to be copied", "Copy Bar"];

  return (
    <div>
      {data.map((text) => (
        <span
          style={{ margin: "10px", cursor: "pointer", color: 'red' }}
          onClick={() => copyToClipboard(text)}
        >
          {text}
        </span>
      ))}
    </div>
  );
};

const domContainer = document.querySelector('#app');
ReactDOM.render(<Element />, domContainer);
    <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

    <div id="app"> </div>


推荐阅读