React计算门票总价时返回NaN问题排查
问题根因
你的代码存在多处React基础逻辑错误,直接导致计算返回NaN:
- 作用域完全错误:
adultTickets、minorTickets是TicketCounter组件内部的局部变量,TotalCost组件根本无法访问这两个值,拿到的永远是undefined。而且这两个数组每次组件重渲染都会被重置为空数组,你写的push/pop逻辑根本持久化不了数据。 - 状态更新逻辑错误:React的state更新是异步批处理的,你调用
setCounter之后立刻push当前的counterAdult,拿到的是更新前的旧值,不是修改后的新值;另外数组的pop()方法本身不需要传参数,你传入参数也不会生效。另外你把useState的解构写在了组件内部,每次组件渲染都会重复执行该逻辑,不符合React规范。 - 总价计算逻辑完全失效:
- 你定义的
adultCost、minorCost是箭头函数,但全程没有调用这两个函数,直接对函数本身执行Number()转换,函数类型转数字的结果就是NaN - 就算你调用了这两个函数,函数内部还会把原本是函数的
adultCost/minorCost重新赋值为数字,且forEach循环每次都会覆盖计算值,最后拿到的只是数组最后一个元素乘单价,根本不是总票价 - 最后挂载
TotalCost的代码里,ReactDOM.render的第一个参数是空的,组件根本没有被正确挂载到页面上。
- 你定义的
- 命名不规范:两个state的setter命名混乱,一个叫
setCounter一个叫counterSet,很容易出现调用错误。
修正方案
你完全不需要额外维护两个数组存票量,成人票、儿童票的数量直接用state存储即可,总价直接通过state值实时计算,不需要额外的遍历逻辑。如果要拆分组件,就把共享状态抬到父组件,通过props传递给子组件,不要跨组件访问内部变量。
最简可运行修正代码如下:
const { useState } = React; function TicketPage() { // 规范命名state和setter const [adultCount, setAdultCount] = useState(0); const [minorCount, setMinorCount] = useState(0); // 直接基于state实时计算总价,无额外副作用 const totalCost = adultCount * 25 + minorCount * 10; return ( <> <div className="ticket-options"> <div className="option-adult"> <p>Adult Tickets (16yrs+)</p> <div className="ticket-amount"> <img src="../images/arrowup.png" alt="arrow up" className="arrow-up-adult" onClick={() => setAdultCount(prev => prev + 1)} /> <span className="number-adult">{adultCount}</span> <img src="../images/arrowdown.png" alt="arrow down" className="arrow-down-adult" onClick={() => setAdultCount(prev => prev > 0 ? prev - 1 : 0)} /> </div> </div> <div className="option-minor"> <p>Minor Tickets (15yrs-)</p> <div className="ticket-amount"> <img src="../images/arrowup.png" alt="arrow up" className="arrow-up-minor" onClick={() => setMinorCount(prev => prev + 1)} /> <span className="number-minor">{minorCount}</span> <img src="../images/arrowdown.png" alt="arrow down" className="arrow-down-minor" onClick={() => setMinorCount(prev => prev > 0 ? prev - 1 : 0)} /> </div> </div> </div> <div className="option-cost"> <p>Ticket cost: ${totalCost}</p> </div> </> ) } ReactDOM.render(<TicketPage />, document.querySelector(".ticket-counter"));
内容的提问来源于stack exchange,提问作者paparonnie
相关产品推荐
相关产品推荐

