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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:27:03