基于Chakra UI useClipboard实现多Redux输入框复制功能求助
解决多输入框复制到剪贴板的问题
你的代码失效主要有两个原因:
- 所有输入框共用同一个
useClipboard实例,导致复制状态(hasCopied)和目标值(value)互相干扰,复制其中一个输入框后,另一个的按钮也会显示"Copied!"。 - 输入框是受控组件,值来自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
相关产品推荐
相关产品推荐

