useCopy

剪贴板复制 hook,Clipboard API 优先,非安全上下文自动降级

./web 子入口导出:import {useCopy} from '@skyroc/hooks/web'。RN 端不可用。
function useCopy(): {
  copied: boolean;
  copiedText: string;
  copy: (text: string) => Promise<boolean>;
};
返回类型说明
copiedboolean最近一次是否复制成功
copiedTextstring最近一次成功复制的文本
copy(text: string) => Promise<boolean>执行复制,返回是否成功
import { useCopy } from '@skyroc/hooks/web';

interface CopyButtonProps {
  /** 待复制的文本 */
  text: string;
}

const CopyButton = (props: CopyButtonProps) => {
  const { text } = props;

  const { copied, copy } = useCopy();

  return (
    <button
      type="button"
      onClick={() => copy(text)}
    >
      {copied ? '已复制' : '复制'}
    </button>
  );
};

两条路径

if (navigator.clipboard && window.isSecureContext) {
  await navigator.clipboard.writeText(text);
} else {
  await legacyCopy(text);
}

legacyCopy 建一个视觉上不可见(position: fixed 移出视口 + opacity: 0 + pointer-events: none + tabIndex: -1 + readonly)的 textareaselect() 后走 document.execCommand('copy'),最后在 finally 里移除节点。

这条降级路径是给 HTTP 内网环境准备的——navigator.clipboard 只在安全上下文(HTTPS / localhost)可用。

行为约定

情况结果
text 为空串直接返回 false,不改状态
复制成功copied = truecopiedText = text,返回 true
复制失败copied = falsecopiedText = '',返回 false

copied 不会自动复位。要做「已复制」两秒后恢复的效果,业务自己起定时器,或直接用返回的 boolean 触发一次性提示。

后台里 @skyroc/web-admin-layouts 用它提供复制能力。

Last updated on