javascript - 一个 btn 的 onClick 我想用 useRef 和 copyToClipboard 获取它的兄弟(输入框)值,将该 btn 的 setState 设置为已复制
问题描述
当用户传递有效链接时,我正在使用缩短 URL API,我获取 API 并使用“map medthod”呈现缩短的 URL 以将它们放入列表中。它在每个映射的“缩短的 URL”旁边都有一个 btn,onClick 我尝试在其中复制到剪贴板并将 btn 的状态从复制更改为已复制。问题是目前它只有在我有 1 个项目时才能正常工作(点击 btn 与 copyToClipboard 一起工作)但如果我有 2 个按钮并且我单击第一个 btn 到 copyToClipboard,它会聚焦映射列表中的最后一个项目并复制(最后一项)第二个 btn 并将所有 btn 的状态设置为复制。我也不明白为什么当我将钥匙传递给控制台时,我在控制台中看不到带有钥匙的 li 标签。有人可以帮我吗。我只想将我单击的 btn 的输入值复制到剪贴板。这里'第一个 btn 的 onCLick 的图像 第二个 btn 获得焦点和控制台中没有键的图像 & 显然它们不在列表中? 这是下面的代码
import { useForm } from "react-hook-form";
import axios from 'axios';
import Loading from '../../images/Ripple-1s-200px.svg';
const Shorten = () => {
// get built in props of react hook form i.e. register,handleSubmit & errors / watch is for devs
const { register, handleSubmit, formState: {errors} } = useForm();
//1. set user original values to pass as params to url
const [link, setLink] = useState('');
//2. set loader initial values to false
const [loading, setLoading] = useState(false);
//3. pass the fetched short link object into an array so we can map
const [displayLinks, setDisplayLinks] = useState([]);
//4. onSubmit form log data into link & showLoader for a breif moment
const onSubmit = (data, event) => {
event.preventDefault();
//puttin data in a variable to pass as url parameter if valid
setLink(data.userLink);
//add loading here after data is set to state
setLoading(!false);
}
//5. fetch the shortened url link using async method to show loading
useEffect(() => {
let unmounted = false;
async function makeGetRequest() {
try {
let res = await axios.get('https://api.shrtco.de/v2/shorten', { params: { url: link } });
//hid loader if u get response from api call
if (!unmounted && res.data.result.original_link) {
setLoading(false);
//add the data to displayLinks array to map
return setDisplayLinks(displayLinks => [...displayLinks, res.data.result]);
}
}
catch (error) {
console.log(error, "inital mount request with no data");
}
}
//invoke the makeGetRequest here
makeGetRequest();
return () => {
unmounted = true;
}
//passing dependency to re-render on change of state value
}, [link]);
//6. intial State of copied or not button
const [copySuccess, setCopySuccess] = useState('Copy');
const inputRef = useRef(null);
//7. onCick of button target it's short url right now it's selecting the last element
const copyToClipboard = (e) => {
e.preventDefault();
inputRef.current.select();
document.execCommand('copy');
// This is just personal preference.
setCopySuccess('Copied');
};
console.log(displayLinks);
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
<label></label>
<input
{...register("userLink", {required: "Please add a link"})}
type="url"
id="userLink"
/>
{errors.userLink && <span>{errors.userLink.message}</span>}
<input type="submit" />
</form>
{
loading ?
<div className="loader" id="loader">
<img src={Loading} alt="Loading" />
</div>
: <ul>
{
displayLinks.map((el) => {
return (
<li key={el.code}>
<div>
<h5>{el.original_link}</h5>
</div>
{
/* Logical shortcut for only displaying the
button if the copy command exists */
document.queryCommandSupported('copy') &&
<form>
<input
ref={inputRef}
defaultValue={el.full_short_link}>
</input>
<button onClick={copyToClipboard}>{copySuccess}</button>
</form>
}
</li>
)
})
}
</ul>
}
</div>
)
}
export default Shorten;
解决方案
这是因为您对所有链接使用单个 ref
您正在遍历所有链接并提供它们<input ref={inputRef} />
。因此 ref 将始终附加到最后一个链接输入
也许不要使用 refs 并使用copyToClipboard
像这样的替代功能
const copyToClipboard = (url) => {
const textField = document.createElement('textarea')
textField.innerText = url
document.body.appendChild(textField)
if (window.navigator.platform === 'iPhone') {
textField.setSelectionRange(0, 99999)
} else {
textField.select()
}
document.execCommand('copy')
textField.remove()
setCopySuccess('Copied');
}
或者
使用类似的库react-copy-to-clipboard
也请通过此链接
推荐阅读
- ios - 二元运算符“==”不能应用于“字符串”和“UInt32”类型的操作数
- javascript - 期望返回值等于 $promise
- phaser-framework - Phaser Game Keyboard Arrow Keys to Mobile Touch
- django - Django: dynamic changing email recepients
- jquery - Generate Dynamic Inputs with Unique Names & IDs
- javascript - Can't manage to download PDF retrieved from BLOB via Servlet
- dialogflow-es - Dialogflow v2 用户输入和执行
- angularjs - How to change other element classes by clicking on an element inside ng-repeat
- python - (Py)Qt5:如何在以编程方式设置当前项目时更新选择
- python-3.x - pytest:为什么我的模拟函数没有被调用