React开发中点击单个Add/Remove按钮触发所有按钮的问题如何解决
问题原因
你当前定义的addButton和removeButton是组件全局共享的状态,所有渲染的水果条目都共用这两个布尔值控制按钮显隐,只要任意按钮点击修改了这两个状态,所有条目的按钮显示都会同步变更,这就是问题的核心诱因。
优化方案
我们可以直接通过判断当前水果是否存在于购物车数组cart中,动态决定显示Add还是Remove按钮,完全不需要额外维护全局的按钮状态,就能实现每个条目按钮独立控制的效果。
优化后完整代码
import { useState } from 'react'; function MyFruits() { const fruitsArray = [ 'banana', 'banana', 'orange', 'orange', 'strawberry', 'blackberry', ]; const unique = [...new Set(fruitsArray)].sort((a, b) => { return a.localeCompare(b); }); const [itemList, setItemList] = useState(fruitsArray); const [cart, setCart] = useState<string[]>([]); const addClick = (fruit: string, index: number) => { // 若需要限制同个水果仅能添加一次,可加上下方注释的判断 // if (cart.includes(fruit)) return; setCart([...cart, fruit]); }; const removeClick = (fruit: string, index: number) => { // 当前逻辑为删除购物车中所有对应水果,若只需删一个可改用下方注释的逻辑 const removeItem = cart.filter((cartItem) => cartItem !== fruit); // const removeItem = [...cart]; // const targetIndex = removeItem.findIndex(item => item === fruit); // if (targetIndex > -1) removeItem.splice(targetIndex, 1); setCart(removeItem); }; return ( <div className="App"> <header className="App-header"> <ul> {unique.map((fruit, index) => ( <div key={index}> <li>{fruit}</li> {/* 若需要保留原有的itemList长度判断,可在判断条件中加回itemList.length !== 1 */} {!cart.includes(fruit) && ( <button onClick={() => addClick(fruit, index)}>Add</button> )} {cart.includes(fruit) && ( <button onClick={() => removeClick(fruit, index)}>Remove</button> )} </div> ))} </ul> <div className="cart"> Cart: {cart.map((cartItem, index) => ( <p key={index}>{cartItem}</p> ))} </div> </header> </div> ); } export default MyFruits;
核心优化点
- 移除冗余的全局按钮状态,改用购物车数据做判断,每个水果条目独立控制自身按钮显隐,彻底解决按钮同步触发的问题
- 删掉无意义的
setItemList操作,减少不必要的状态更新 - 优化类型定义,把参数的
any替换为实际的string、number类型,提升TS类型安全性 - 保留了原有的添加、删除逻辑,同时给出了可选的去重添加、单次删除的实现方案,可按需启用
内容的提问来源于stack exchange,提问作者Nhan Nguyen
相关产品推荐
相关产品推荐

