React中如何实现独立的计数器增减功能?
解决独立票务计数器的问题
你猜的没错,问题就是所有计数器共用了同一个count状态,所以操作任何一个都会同步改变所有显示值。要实现独立计数器,你可以把状态改成对象来存储每个票种的数量,具体修改如下:
步骤1:初始化对象类型的状态
把原来的单个数字状态,改成包含各个票种的对象,每个票种对应初始数量0:
const [counts, setCounts] = useState({ parking: 0, earlyHorror: 0 });
步骤2:修改增减函数,支持指定票种
更新increment和decrement函数,让它们接收一个票种标识(比如parking或earlyHorror),然后只更新对应票种的数量:
function increment(ticketType) { setCounts(prevCounts => ({ ...prevCounts, [ticketType]: prevCounts[ticketType] + 1 })); } function decrement(ticketType) { setCounts(prevCounts => ({ ...prevCounts, [ticketType]: Math.max(prevCounts[ticketType] - 1, 0) // 防止数量小于0 })); }
步骤3:更新UI渲染,绑定对应票种的状态和函数参数
在每个ticket-block里,把输入框的value绑定到对应票种的状态,点击按钮时传递对应的票种标识:
停车票部分修改:
<div className="counter"> <button className="increase-amount" onClick={() => increment('parking')}>+</button> <input type="text" className="amount" value={counts.parking} /> <button className="decrease-amount" onClick={() => decrement('parking')}>-</button> </div>
Early Horror票部分修改:
<div className="counter"> <button className="increase-amount" onClick={() => increment('earlyHorror')}>+</button> <input type="text" className="amount" value={counts.earlyHorror} /> <button className="decrease-amount" onClick={() => decrement('earlyHorror')}>-</button> </div>
完整修改后的代码
import { useState } from 'react'; export default function Ticket() { // 用对象存储每个票种的数量 const [counts, setCounts] = useState({ parking: 0, earlyHorror: 0 }); function increment(ticketType) { setCounts(prevCounts => ({ ...prevCounts, [ticketType]: prevCounts[ticketType] + 1 })); } function decrement(ticketType) { setCounts(prevCounts => ({ ...prevCounts, [ticketType]: Math.max(prevCounts[ticketType] - 1, 0) })); } return ( <div> <section className="ticket-step"> <h1>TICKETS</h1> </section> <div className="ticket-booking is-flexbox"> <section className="ticket-content"> <ul className="tickets-tab is-flexbox"> <li>Tickets</li> <li>Abbonementen</li> </ul> <div className="ticket-list-section"> <div className="ticket-list-details heading"> <div id="calender"> <h3>Datum : 30 - 10 - 2022</h3> </div> <div id="opening"> <h3>Openingstijden: 12:00 - 20:00 </h3> </div> </div> <div className="ticket-list-details"> <div className="ticket-block"> <div className="ticket-title"> <h3>Parkeer ticket</h3> </div> <div className="price"> <h3>Prijs: $20</h3> </div> <div className="counter"> <button className="increase-amount" onClick={() => increment('parking')}>+</button> <input type="text" className="amount" value={counts.parking} /> <button className="decrease-amount" onClick={() => decrement('parking')}>-</button> </div> </div> <div className="ticket-block"> <div className="ticket-title"> <h3>Early Horror-ticket</h3> </div> <div className="price"> <h3>Prijs : $59</h3> </div> <div className="counter"> <button className="increase-amount" onClick={() => increment('earlyHorror')}>+</button> <input type="text" className="amount" value={counts.earlyHorror} /> <button className="decrease-amount" onClick={() => decrement('earlyHorror')}>-</button> </div> </div> </div> </div> </section> <aside className="sidebar-overview"> <h1>besteloverzicht</h1> <div className="sidebar-overview-content"> {/* 实时显示已选票种信息 */} {counts.parking > 0 && ( <div>Parkeer ticket: {counts.parking} x $20 = ${counts.parking * 20}</div> )} {counts.earlyHorror > 0 && ( <div>Early Horror-ticket: {counts.earlyHorror} x $59 = ${counts.earlyHorror * 59}</div> )} </div> <hr/> <div className="sidebar-overview-total"> <h3>Totaal: ${counts.parking * 20 + counts.earlyHorror * 59}</h3> </div> </aside> </div> </div> ) }
额外补充了购物车总计的计算逻辑,侧边栏能实时显示总价,更贴合票务系统的实际需求。
内容的提问来源于stack exchange,提问作者Samsorrr
相关产品推荐
相关产品推荐

