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

如何在React Hooks中禁用onClick已包含setState逻辑的点赞按钮

实现方案

首先梳理原有代码的可优化点:

  • useState的结构不合理:你当前把商品列表和禁用状态包在同一个对象里,后续直接调用items.map会因为items是对象而非数组抛出报错
  • 禁用状态没有和单个商品绑定:如果用全局禁用状态,点击任意一个商品的点赞按钮会导致所有商品的点赞按钮都被禁用,不符合业务逻辑
  • JSX存在标签嵌套错误,部分标签提前闭合导致结构异常

核心修改思路

  1. 给每个商品新增liked字段,单独标记该商品是否已经被点赞
  2. 调整state结构直接存储商品列表
  3. 点赞逻辑执行时同步修改对应商品的liked状态为true
  4. 给点赞按钮绑定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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:15:05