react中使用复制的功能

在react中使用最新的navigator.clipboard.writeText(url)方法来实现复制的功能

javascript 复制代码
import React, { FC, useRef, useMemo } from 'react'
import { Space, Button, Typography, Input, Tooltip, message, Popover } from 'antd'
import type { InputRef } from 'antd'
import { LeftOutlined, CopyOutlined, QrcodeOutlined } from '@ant-design/icons'
import { useNavigate, useParams } from 'react-router-dom'
import QRCode from 'qrcode.react'
import useGetPageInfo from '../../../hooks/useGetPageInfo'
import styles from './StatHeader.module.scss'

const { Title } = Typography

/**
 * 统计页头部组件
 * 负责展示问卷标题、返回按钮、分享链接/二维码以及编辑入口
 */
const StatHeader: FC = () => {
  // 获取路由跳转函数
  const nav = useNavigate()
  // 获取路由参数中的问卷 ID
  const { id } = useParams()

  // 使用自定义 Hook 获取问卷页面信息(标题、是否已发布)
  const { title, isPublished } = useGetPageInfo()

  // 创建一个 ref 来引用链接输入框,用于获取 URL 值(虽然这里直接拼接了,但保留了通过 DOM 获取的逻辑)
  const urlInputRef = useRef<InputRef>(null)

  /**
   * 复制链接到剪贴板的异步函数
   * 使用现代 Clipboard API 实现
   */
  async function copy() {
    const elem = urlInputRef.current
    if (elem == null) return
    
    // 从输入框元素中获取 URL 值
    // 注意:这里使用了可选链操作符,防止 elem.input 为 undefined
    const url = elem.input?.value || ''
    
    try {
      // 调用浏览器原生 API 写入剪贴板
      await navigator.clipboard.writeText(url)
      message.success('拷贝成功')
    } catch (err) {
      // 捕获并处理写入失败的情况(如权限被拒、非安全上下文等)
      message.error('拷贝失败')
      console.error('Failed to copy: ', err)
    }
  }

  // 使用 useMemo 进行性能优化:仅当 id 或 isPublished 变化时重新计算
  // 目的:避免每次渲染都重新创建复杂的 JSX 元素(包含 Input, Button, QRCode),减少重渲染开销
  const LinkAndQRCodeElem = useMemo(() => {
    // 如果问卷未发布,则不显示分享组件
    if (!isPublished) return null

    // 拼接问卷的访问 URL (基于 C 端访问规则)
    // 注意:此处为本地开发环境地址,生产环境需替换为正式域名
    const url = `http://localhost:3000/question/${id}`

    // 定义二维码弹窗的内容组件
    const QRCodeElem = (
      <div style={{ textAlign: 'center' }}>
        {/* 使用 qrcode.react 库生成二维码,指定大小为 150px */}
        <QRCode value={url} size={150} />
      </div>
    )

    // 返回包含链接输入框、复制按钮和二维码按钮的工具栏
    return (
      <Space>
        {/* 只读输入框显示链接 */}
        <Input 
          value={url} 
          style={{ width: '300px' }} 
          ref={urlInputRef} 
        />
        
        {/* 复制链接按钮,带 Tooltip 提示 */}
        <Tooltip title="拷贝链接">
          <Button 
            icon={<CopyOutlined />} 
            onClick={copy} // 点击触发复制逻辑
          />
        </Tooltip>
        
        {/* 二维码弹窗按钮 */}
        <Popover content={QRCodeElem}>
          <Button icon={<QrcodeOutlined />} />
        </Popover>
      </Space>
    )
  }, [id, isPublished]) // 依赖数组:只有当问卷 ID 或发布状态改变时才重新执行

  return (
    <div className={styles['header-wrapper']}>
      <div className={styles.header}>
        {/* 左侧:返回按钮和问卷标题 */}
        <div className={styles.left}>
          <Space>
            <Button 
              type="link" 
              icon={<LeftOutlined />} 
              onClick={() => nav(-1)} // 点击返回上一页
            >
              返回
            </Button>
            <Title level={3} style={{ margin: 0 }}>{title}</Title>
          </Space>
        </div>
        
        {/* 中间:链接与二维码分享区域(仅在发布后显示) */}
        <div className={styles.main}>{LinkAndQRCodeElem}</div>
        
        {/* 右侧:编辑问卷入口 */}
        <div className={styles.right}>
          <Button 
            type="primary" 
            onClick={() => nav(`/question/edit/${id}`)} // 跳转到编辑页面
          >
            编辑问卷
          </Button>
        </div>
      </div>
    </div>
  )
}

export default StatHeader
相关推荐
BigTopOne7 小时前
【WebRtc】DTLS-SRTP 加密完整流程详解
前端
陈随易7 小时前
pm2 替代品,nodejs&bun 线上部署必备工具
前端·后端·程序员
单线程_017 小时前
从案例分析 Vue3 Tokenizer 源码一
前端·javascript·vue.js
BigTopOne7 小时前
【WebRtc】-ICE Candidate 与 STUN/TURN 原理详解
前端
l1258657 小时前
# LangGraph Memory机制深度解析:短期记忆与长期记忆的工程实践
前端·人工智能·python·langchain·bootstrap
码视野7 小时前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
大模型码小白7 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
m0_547486668 小时前
《JavaScript核心原理 》全套PPT课件2026
开发语言·javascript·ecmascript
xm_xm_xm_18 小时前
react17版本以前类组件常用操作
前端·javascript·react.js
ly76899 小时前
Web 性能优化实战:从 Core Web Vitals 到工程化性能治理
前端·性能优化