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> ))} </> ) }
关键改进点说明
- 状态结构调整:从单个对象改为存储所有按钮状态的集合(对象/Set),避免覆盖旧状态
- 使用唯一标识:用
id而非name作为判断依据,避免名称重复导致的状态混乱 - 正确更新状态:使用函数式更新(
prevState/prevSet)确保基于最新状态修改,避免闭包问题 - TypeScript类型规范:移除
any,明确状态的类型定义,提升代码可靠性
内容的提问来源于stack exchange,提问作者Himanshu Sharma
相关产品推荐
相关产品推荐

