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

React实现点击购买建筑并单独更新对应状态的方法

解决方案

1. 给JSON建筑数据添加唯一标识

你的自定义JSON文件里的每个建筑,需要新增一个和buildingsOwned对象键名对应的唯一id字段,确保能匹配到state里的对应项,示例如下:

[
  {
    "id": "buildingOne",
    "name": "基础建筑",
    "url": "./path/to/image1.png",
    "cost": 100
  },
  {
    "id": "buildingTwo",
    "name": "进阶建筑",
    "url": "./path/to/image2.png",
    "cost": 1000
  },
  {
    "id": "buildingThree",
    "name": "高级建筑",
    "url": "./path/to/image3.png",
    "cost": 10000
  }
]

2. 实现buyBuilding的state更新逻辑

使用函数式更新结合扩展运算符,复制原state并仅修改被点击建筑的数量:

const buyBuilding = (building) => {
  setBuildingsOwned(prevState => ({
    ...prevState,
    // 通过建筑id匹配state中的对应字段,数量+1
    [building.id]: prevState[building.id] + 1
  }));
}

用函数式更新(prevState)是因为新状态依赖于旧状态的值,能避免异步更新导致的状态不一致问题。

3. 传递状态并显示真实拥有数量

把buildingsOwned作为props传给LeftMenu,并在渲染时根据建筑id获取对应数量:

// 父组件中传递props
<LeftMenu 
  buildingsList={buildingsList} 
  buyBuilding={buyBuilding} 
  buildingsOwned={buildingsOwned} 
/>

// 修改LeftMenu组件
function LeftMenu({ buildingsList, buyBuilding, buildingsOwned }) {
  return (
    <section className="left-menu">
      <h2>Buildings</h2>
      {buildingsList.map((building) => {
        return (
            <div className="item" key={building.id}>
              <img src={building.url} alt="merchant building" />
              <div>{building.name}</div>
              <div>£{building.cost}</div>
              <div>Owned: {buildingsOwned[building.id]}</div>
              <button onClick={() => buyBuilding(building)}>Buy</button>
            </div>
        );
      })}
    </section>
  );
}

额外优化点

  • 把列表项的key从index换成建筑的id,让React列表渲染更高效
  • 可以在buyBuilding里添加货币校验逻辑,比如判断玩家当前货币是否足够购买该建筑,避免无效的数量增加

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:12:49