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
相关产品推荐
相关产品推荐

