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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:45:34