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

React使用map渲染列表时如何单独修改单个元素的状态值

问题原因

你当前所有的复制按钮共用了同一个全局的buttonText状态,只要触发一次状态修改,所有绑定该状态的按钮文本都会同步更新,因此会出现点击任意按钮所有按钮都变"Copied"的问题。

实现方案

我们可以给每个短链接项单独加复制状态标记,实现单个按钮状态独立控制,步骤如下:

  • 移除全局的buttonText状态,改为在短链接列表的每个条目里新增copied字段,默认值为false,单独记录每个按钮的复制状态
  • 渲染按钮时根据当前条目的copied字段判断显示文本
  • 点击复制按钮时,仅修改当前点击条目对应的copied状态,还可加定时重置逻辑提升使用体验

修正后代码

import {useState} from 'react'
import axios from 'axios'
import { v4 as uuidv4 } from 'uuid';

function Main() {
    const [name, setName] = useState('')
    // 初始列表如果有默认值,也要给每个项加copied: false字段
    const [list, setList] = useState([]);
    const handleSubmit = (e) => {
        e.preventDefault();
    }
    const handleAdd = async () => {
        const res = await axios.get(`https://api.shrtco.de/v2/shorten?url=${name}`)
        const {data: {result: {full_short_link: shortLink}}} = res 
        // 新增项添加copied字段,默认为false
        const newList = list.concat({name:shortLink, id: uuidv4(), copied: false});
        setList(newList);
        setName('');
    }

    // 复制按钮点击处理
    const handleCopy = (item) => {
        navigator.clipboard.writeText(item.name);
        // 仅更新当前点击项的copied状态
        setList(prevList => prevList.map(link => {
            if(link.id === item.id) {
                return {...link, copied: true}
            }
            return link
        }))
        // 可选:2秒后自动变回Copy文本
        setTimeout(() => {
            setList(prevList => prevList.map(link => {
                if(link.id === item.id) {
                    return {...link, copied: false}
                }
                return link
            }))
        }, 2000)
    }

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type="text" 
                value= {name} 
                onChange={(e) => setName(e.target.value)}
                placeholder='Shorten a link here'
                />
                <button onClick = {handleAdd}>Shorten it!</button>
            </form>
            
            <ul>
                {list.map((item) => (
                <li key={item.id}>
                    {item.name}
                    <button onClick={() => handleCopy(item)}>
                        {/* 根据当前项的copied状态显示对应文本 */}
                        {item.copied ? 'Copied' : 'Copy'}
                    </button>
                </li>
                ))}
            </ul>
        </div>
    )
}

export default Main

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:15:04