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

React+TypeScript中如何保留多按钮点击后的状态不重置

解决方案

你的问题核心在于当前的status状态只能记录单个按钮的状态,每次点击新按钮都会覆盖之前的记录,导致旧按钮的状态被重置。要保留所有按钮的状态,需要为每个独立的按钮维护状态,以下是两种可行的实现方式:

方式一:用对象存储每个按钮的状态

通过对象来记录每个ID(推荐用ID,避免名称重复)对应的点击状态,键为唯一标识,值为布尔值表示是否已点击。

const sampleData = [
    {id : 1, name : 'Adam'},
    {id : 2, name : 'Stephanie'},
    {id : 3, name : 'Mark'},
    {id : 4, name : 'Catherine'},
    {id : 5, name : 'Kate'},
    {id : 6, name : 'Max'},
    {id : 7, name : 'Jacob'},
    {id : 8, name : 'John'}
];

export default function MyComponent () {
    // 用对象存储每个ID的点击状态,初始为空对象
    const [clickedStatus, setClickedStatus] = useState<Record<number, boolean>>({});

    const handleAddClick = (id: number) => {
        setClickedStatus(prevState => ({
            ...prevState,
            // 切换当前ID的状态:已点击则改为false,未点击则改为true
            [id]: !prevState[id]
        }));
    }

    return (
        <>
            {sampleData.map((data) => (
                <div key={data.id}>
                    <Typography>{data.name}</Typography>
                    <Button 
                        onClick={() => handleAddClick(data.id)}
                        className={clickedStatus[data.id] ? 'changeColor' : ''}
                    >
                        {/* 根据状态切换按钮文字 */}
                        {clickedStatus[data.id] ? 'Added' : 'Add'}
                    </Button>
                </div>
            ))}
        </>
    )
}

方式二:用Set存储已点击的按钮ID

如果只需要记录按钮是否被点击(不需要额外状态),用Set会更简洁,Set自动处理唯一性,适合存储已选中的ID集合。

const sampleData = [
    {id : 1, name : 'Adam'},
    {id : 2, name : 'Stephanie'},
    {id : 3, name : 'Mark'},
    {id : 4, name : 'Catherine'},
    {id : 5, name : 'Kate'},
    {id : 6, name : 'Max'},
    {id : 7, name : 'Jacob'},
    {id : 8, name : 'John'}
];

export default function MyComponent () {
    // 用Set存储已点击的ID,初始为空Set
    const [clickedIds, setClickedIds] = useState<Set<number>>(new Set());

    const handleAddClick = (id: number) => {
        setClickedIds(prevSet => {
            const newSet = new Set(prevSet);
            if (newSet.has(id)) {
                newSet.delete(id); // 已点击则取消
            } else {
                newSet.add(id); // 未点击则添加
            }
            return newSet;
        });
    }

    return (
        <>
            {sampleData.map((data) => (
                <div key={data.id}>
                    <Typography>{data.name}</Typography>
                    <Button 
                        onClick={() => handleAddClick(data.id)}
                        className={clickedIds.has(data.id) ? 'changeColor' : ''}
                    >
                        {clickedIds.has(data.id) ? 'Added' : 'Add'}
                    </Button>
                </div>
            ))}
        </>
    )
}

关键改进点说明

  1. 状态结构调整:从单个对象改为存储所有按钮状态的集合(对象/Set),避免覆盖旧状态
  2. 使用唯一标识:用id而非name作为判断依据,避免名称重复导致的状态混乱
  3. 正确更新状态:使用函数式更新(prevState/prevSet)确保基于最新状态修改,避免闭包问题
  4. TypeScript类型规范:移除any,明确状态的类型定义,提升代码可靠性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:01:01