如何在React Hooks中禁用onClick已包含setState逻辑的点赞按钮
实现方案
首先梳理原有代码的可优化点:
- useState的结构不合理:你当前把商品列表和禁用状态包在同一个对象里,后续直接调用
items.map会因为items是对象而非数组抛出报错 - 禁用状态没有和单个商品绑定:如果用全局禁用状态,点击任意一个商品的点赞按钮会导致所有商品的点赞按钮都被禁用,不符合业务逻辑
- JSX存在标签嵌套错误,部分标签提前闭合导致结构异常
核心修改思路
- 给每个商品新增
liked字段,单独标记该商品是否已经被点赞 - 调整state结构直接存储商品列表
- 点赞逻辑执行时同步修改对应商品的
liked状态为true - 给点赞按钮绑定
disabled属性,值为当前商品的liked字段值
修改后完整代码
const allItems = [ { id: 1, name: "The Rise and Decline of Patriarchal Systems", image: "https://img.thriftbooks.com/api/images/i/m/8ECA8C9BAF351D13622ADFFBFA8A5D4E2BAABAFF.jpg", likes: 3359, price: 1, liked: false // 新增单个商品点赞标记 } ] const Shop = () => { // 调整state结构,直接存储商品数组 const [items, setItems] = React.useState(allItems) const updateLike = (item) => setItems(items.map(indItem => { if (indItem.id !== item.id) { // 改用id判断更稳妥,避免引用类型判断异常 return indItem } else { // 点赞同时标记为已点赞 return {...item, likes: item.likes + 1, liked: true} } })) const listItemsToBuy = () => items.map((item) => ( // 修复标签嵌套错误 <div key={item.id} className="card"> <div className="font-text"> <h2>{item.name}</h2> </div> <h2>Likes: {item.likes}</h2> <div> {/* 绑定disabled属性,已点赞就禁用按钮 */} <button onClick={()=> updateLike(item)} disabled={item.liked} > {item.liked ? '已点赞' : 'Like'} </button> </div> </div> )); // 补充原代码缺失的组件返回逻辑 return <div className="shop-container"> {listItemsToBuy()} </div> }
额外优化说明
- 把原逻辑里的引用相等判断
indItem !== item改成了id相等判断,避免因为数组引用变化导致判断失效的问题 - 按钮文字根据点赞状态动态切换,用户体验更友好
- 修复了原代码中缺失的组件返回值、标签闭合等语法问题
内容的提问来源于stack exchange,提问作者pola
相关产品推荐
相关产品推荐

