You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Chakra UI useClipboard实现多Redux输入框复制功能求助

解决多输入框复制到剪贴板的问题

你的代码失效主要有两个原因:

  1. 所有输入框共用同一个useClipboard实例,导致复制状态(hasCopied)和目标值(value)互相干扰,复制其中一个输入框后,另一个的按钮也会显示"Copied!"。
  2. 输入框是受控组件,值来自Redux Store,onChange里调用setValue完全多余——没有dispatch action更新Redux状态的话,输入框的值不会改变,反而会让useClipboard的value和实际输入值脱节。

下面提供两种可行的解决方案:

方案一:为每个输入框单独创建剪贴板实例

每个输入框对应独立的useClipboard,状态互不影响,直接用Redux的值初始化剪贴板:

import { useClipboard } from "@chakra-ui/react";
import { useSelector } from "react-redux";

const YourComponent = () => {
  const { token } = useSelector((state) => state.apikeys);
  // 为token创建独立剪贴板实例
  const { onCopy: copyToken, hasCopied: hasCopiedToken } = useClipboard(token);
  // 为生产密钥创建独立剪贴板实例
  const { onCopy: copyProdKey, hasCopied: hasCopiedProdKey } = useClipboard(prodkey.prodKey);

  return (
    <>
      <InputGroup>
        {/* 设为只读,避免用户修改(如需修改需同步更新Redux状态) */}
        <Input value={token} readOnly />
        <InputRightElement>
          <Button onClick={copyToken}>
            {hasCopiedToken ? "Copied!" : "Copy"}
          </Button>
        </InputRightElement>
      </InputGroup>

      <InputGroup>
        <Input value={prodkey.prodKey} readOnly />
        <InputRightElement>
          <Button onClick={copyProdKey}>
            {hasCopiedProdKey ? "Copied!" : "Copy"}
          </Button>
        </InputRightElement>
      </InputGroup>
    </>
  );
};

方案二:手动控制复制内容和状态

使用单个useClipboard实例的copy方法直接指定复制内容,自己维护每个输入框的复制状态:

import { useClipboard } from "@chakra-ui/react";
import { useSelector } from "react-redux";
import { useState } from "react";

const YourComponent = () => {
  const { token } = useSelector((state) => state.apikeys);
  const { copy } = useClipboard();
  // 单独维护每个输入框的复制状态
  const [copiedStatus, setCopiedStatus] = useState({
    token: false,
    prodKey: false
  });

  const handleCopy = (targetKey, content) => {
    // 复制指定内容
    copy(content);
    // 设置对应输入框的复制状态
    setCopiedStatus(prev => ({ ...prev, [targetKey]: true }));
    // 3秒后重置状态,恢复显示"Copy"
    setTimeout(() => {
      setCopiedStatus(prev => ({ ...prev, [targetKey]: false }));
    }, 3000);
  };

  return (
    <>
      <InputGroup>
        <Input value={token} readOnly />
        <InputRightElement>
          <Button onClick={() => handleCopy("token", token)}>
            {copiedStatus.token ? "Copied!" : "Copy"}
          </Button>
        </InputRightElement>
      </InputGroup>

      <InputGroup>
        <Input value={prodkey.prodKey} readOnly />
        <InputRightElement>
          <Button onClick={() => handleCopy("prodKey", prodkey.prodKey)}>
            {copiedStatus.prodKey ? "Copied!" : "Copy"}
          </Button>
        </InputRightElement>
      </InputGroup>
    </>
  );
};

两种方案都能解决你的问题,方案一更简洁,方案二更灵活,可根据需求选择。

内容的提问来源于stack exchange,提问作者God_favorite_customer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:45:10