React Hooks中单选按钮输入计算总价格功能异常问题求助
问题排查与修复方案
核心问题1:重复onClick属性覆盖
React元素的同一个属性只能赋值一次,你给单个input写了3个onClick,只有最后一个calcTotPrice会生效,前面修改size、sizePrice的逻辑完全不会执行,这是计算不生效的最主要原因。
核心问题2:状态更新异步导致计算取值旧
React的setState是异步批量更新的,就算你把修改状态和计算总价放到同一个回调里,调用setSizePrice后立刻执行calcTotPrice,拿到的还是更新前的sizePrice值,计算结果会错位。
其他小问题
- 数量状态的setter拼写错误:
setQuentity应该为setQuantity,后续修改数量时会触发报错 totPrice属于派生状态,不需要单独用useState存储,直接通过三个依赖项计算即可,能完全避免状态不同步的问题
修复后代码示例
简化状态定义
// 只保留需要用户操作修改的状态,总价等派生值直接计算即可 const [quantity, setQuantity] = useState(1) const [size, setSize] = useState('medium') const [topping, setTopping] = useState('none') // 尺寸价格映射,随size变化自动更新 const sizePrice = { small: product.smallPrice, medium: product.mediumPrice, large: product.largelPrice // 注意确认product中large价格的字段名是否和拼写一致 }[size] // 配料价格映射,随topping变化自动更新 const toppingPrice = { none: 0, 'Fresh Fruit': product.freshFruitToppingPrice, 'Candies & Cashew Nut': product.chocolateCandiesAndCashewNutToppingPrice, 'Moldable Fondan': product.moldableFondanToppingPrice }[topping] // 总价自动计算,依赖任意一项变化都会自动更新,不需要手动调用计算函数 const totPrice = (sizePrice + toppingPrice) * quantity
修复单选按钮绑定逻辑
同一个元素仅保留一个onClick,所有操作放到同一个回调中:
<div className="selectButton"> <div className="radio-container"> <input id="500g" name="size" type="radio" value="500g" onClick={() => setSize('small')} /> <label htmlFor="500g">500 g</label> <input defaultChecked id="1Kg" name="size" type="radio" value="1Kg" onClick={() => setSize('medium')} /> <label htmlFor="1Kg">1 Kg</label> <input id="2Kg" name="size" type="radio" value="2Kg" onClick={() => setSize('large')} /> <label htmlFor="2Kg">2 Kg</label> </div> </div> <div className="selectButton"> <div className="radio-container2"> <input defaultChecked id="0" name="topping" type="radio" value="0" onClick={() => setTopping('none')} /> <label htmlFor="0">None</label><br /> <input id="1" name="topping" type="radio" value="1" onClick={() => setTopping('Fresh Fruit')} /> <label htmlFor="1">Fresh Fruit</label><br /> <input id="2" name="topping" type="radio" value="2" onClick={() => setTopping('Candies & Cashew Nut')} /> <label htmlFor="2">Candies & Cashew Nut</label><br /> <input id="3" name="topping" type="radio" value="3" onClick={() => setTopping('Moldable Fondan')} /> <label htmlFor="3">Moldable Fondan</label> </div> </div>
内容的提问来源于stack exchange,提问作者Paula De Silva
相关产品推荐
相关产品推荐

