Clipboard API:在 React 中复制和粘贴
使用现代 Clipboard API 实现复制到剪贴板按钮,并为旧版浏览器提供平稳的降级方案
Clipboard API:在 React 中复制和粘贴 是 CoddyKit 上的免费 React Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
写入剪贴板
navigator.clipboard.writeText(text) 会将字符串写入系统剪贴板,并返回一个 Promise。它是旧版 execCommand 方案的现代替代方法。请始终等待这个 Promise,并处理可能的拒绝情况,例如用户拒绝剪贴板访问时。
读取剪贴板
navigator.clipboard.readText() 会将当前剪贴板内容读取为字符串,并同样返回一个 Promise。读取需要 clipboard-read 权限,浏览器会提示用户授予该权限。在实际的 React 应用中,读取剪贴板的使用频率通常低于写入剪贴板。
写入剪贴板需要用户手势
浏览器强制要求只能在用户手势处理程序中调用 clipboard.writeText,例如点击或按键事件处理程序。在 useEffect 中调用,或在手势发生后异步调用,都会抛出安全错误。请始终直接从 onClick 处理程序触发写入。
复制到剪贴板的界面模式
标准模式如下:用户点击复制按钮,您的处理程序调用 navigator.clipboard.writeText(value),成功后将 copied 状态设置为 true,按钮暂时显示对勾或“已复制!”标签。经过短暂延迟后,按钮会恢复正常状态。
构建 useCopyToClipboard 钩子
请将这段逻辑封装在 useCopyToClipboard 钩子中,使其返回一个元组:[copied, copyFn]。copied 布尔值负责驱动界面反馈,copyFn 接受要复制的文本。该钩子会在内部处理异步写入和任何错误,从而让组件保持简洁。
重置已复制状态
在钩子内部,复制成功后设置 setCopied(true),并通过 setTimeout(() => setCopied(false), 2000) 安排重置。请保存超时 ID,并在 useEffect 的清理函数中清除它,以防组件卸载后仍更新状态。这样可以避免出现“无法更新已卸载组件上的状态”警告。
使用 execCommand 的旧版备用方案
较旧的浏览器和非 HTTPS 页面不支持剪贴板接口。旧版备用方案会创建一个临时的 textarea,设置其值,将它附加到文档主体,调用 document.execCommand('copy'),然后移除该元素。这种方法是同步的,几乎在所有环境中都能运行,但已经被弃用。
检测剪贴板接口是否可用
使用剪贴板接口之前,请检查:navigator.clipboard && typeof navigator.clipboard.writeText === 'function'。如果不可用,请改用旧版的 execCommand 方案。这项防御性检查可以避免在不支持该接口的环境中出现运行时错误。
剪贴板读取权限
读取剪贴板需要通过权限接口获得用户许可。您可以查询当前状态:navigator.permissions.query({ name: 'clipboard-read' }) 会返回一个 PermissionStatus,其 state 为 granted、denied 或 prompt。调用 readText() 时,浏览器会自动提示用户。
HTTPS 要求
剪贴板接口仅在安全上下文(HTTPS 或 localhost)中可用。在 HTTP 页面上,navigator.clipboard 是 undefined。这是出于安全限制,因为剪贴板内容可能包含敏感信息。请始终先检查接口是否可用,再引用其方法,以避免出现空引用错误。
在 jsdom 中测试剪贴板
jsdom(由 Jest 使用)未实现剪贴板接口。请在测试设置中对其进行模拟:Object.assign(navigator, { clipboard: { writeText: jest.fn().mockResolvedValue(undefined) } })。这样,您无需真实的浏览器环境,就可以测试组件是否使用正确的参数调用 writeText。
剪贴板写入要求
在浏览器中,何时可以安全地调用 navigator.clipboard.writeText()?
课程回顾:React 中的剪贴板接口
在点击处理函数中使用 navigator.clipboard.writeText() 来复制文本。构建一个返回 [copied, copyFn] 并带有定时重置功能的 useCopyToClipboard 钩子。始终检查接口是否可用,为较旧的浏览器提供 execCommand 回退方案,并在 Jest 测试中模拟 navigator.clipboard。
常见问题解答
「Clipboard API:在 React 中复制和粘贴」课时是免费的吗?
是的 — 「Clipboard API:在 React 中复制和粘贴」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「Clipboard API:在 React 中复制和粘贴」这节课中我会学到什么?
使用现代 Clipboard API 实现复制到剪贴板按钮,并为旧版浏览器提供平稳的降级方案 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「Clipboard API:在 React 中复制和粘贴」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Clipboard API:在 React 中复制和粘贴
- React 组件中的 Geolocation API
- Notifications API 与权限处理
- 使用 IntersectionObserver 实现滚动触发效果