ReactJS Hooks 基于其他State设置状态时未立即渲染问题求解
问题原因
React 中的 useState 更新是异步批量执行的,你在同一个 calculate 函数内调用 setWeight、setPricePerGr 之后,当前函数作用域内拿到的 weight、pricePerGr 还是本次函数执行前的旧值,并不是刚设置的新值。所以你后续计算 totalPrice 时用的是旧的 weight、pricePerGr,计算 payment 时用的是旧的 totalPrice,才会出现需要点击三次才能逐步拿到正确值的情况。
解决方案
方案1:基于输入框最新值直接计算(改动最小)
不要依赖刚 setState 后还没更新的状态值,先把输入框的最新值转成数字存在临时变量里,所有计算都基于这个临时变量执行:
const [weight, setWeight] = useState(0) const [pricePerGr, setPricePerGr] = useState(0) const [totalPrice, setTotalPrice] = useState(0) const [payment, setPayment] = useState(0) const calculate = () => { // 先拿到最新的输入值,转成数字避免字符串运算问题 const newWeight = Number(weightInput.value) const newPricePerGr = Number(priceInput.value) const newTotalPrice = newWeight * newPricePerGr const newPayment = newTotalPrice * 80 / 100 // 一次性更新所有state setWeight(newWeight) setPricePerGr(newPricePerGr) setTotalPrice(newTotalPrice) setPayment(newPayment) } <Button onClick={calculate}>Calculate</Button> <div> weight: {weight} price per grams: {pricePerGr} Total Price: {totalPrice} Payment: {payment} </div>
方案2:移除冗余的派生状态(更推荐)
totalPrice、payment 完全可以通过已有的 weight、pricePerGr 直接计算得到,不需要单独存为 state,既减少冗余代码也不会出现状态不同步的问题:
const [weight, setWeight] = useState(0) const [pricePerGr, setPricePerGr] = useState(0) // 直接计算派生值,每次weight/pricePerGr变化会自动重新计算 const totalPrice = weight * pricePerGr const payment = totalPrice * 80 / 100 const calculate = () => { setWeight(Number(weightInput.value)) setPricePerGr(Number(priceInput.value)) } <Button onClick={calculate}>Calculate</Button> <div> weight: {weight} price per grams: {pricePerGr} Total Price: {totalPrice} Payment: {payment} </div>
内容的提问来源于stack exchange,提问作者anggasantoso
相关产品推荐
相关产品推荐

