为何Select组件需两次选择才能更新state?
问题原因:React状态更新的异步特性
这个问题的核心是React中useState的状态更新是异步操作:
- 当你在
onChange里调用setVehicleBodyId(e.value)时,React不会立刻修改vehicleBodyId的当前值,而是把这次更新加入到状态更新队列中,要等到组件下一次渲染时才会真正更新这个状态变量。 - 所以紧接着调用
handleRecalculateReservationAmount(3, 4, vehicleBodyId)的时候,vehicleBodyId还是更新前的旧值,这就导致第一次选择下拉项时,传入函数的id是之前选中的旧值。 - 第二次选择时,组件已经完成了上一次的状态更新和渲染,此时
vehicleBodyId已经是第一次选择的新值,所以这次调用函数时传入的是第一次的id,看起来像是“第二次才更新”,本质是每次都慢了一拍。
修复方案
方案1:直接使用事件中的新值
既然e.value就是当前选中的新id,直接把它传给计算函数即可,不用等待状态更新:
onChange={(e: any) => { setVehicleBodyId(e.value) // 直接用e.value代替vehicleBodyId handleRecalculateReservationAmount(3, 4, e.value) }}
方案2:用useEffect监听状态变化
如果后续逻辑需要依赖更新后的vehicleBodyId,可以用useEffect监听状态变化,当状态更新后再执行计算:
import { useEffect } from 'react' const EditBookingDetailsModal = () => { // ... 其他代码不变 useEffect(() => { // 状态更新后执行计算 if (vehicleBodyId) { handleRecalculateReservationAmount(3, 4, vehicleBodyId) } }, [vehicleBodyId, handleRecalculateReservationAmount]) // 添加依赖项 return ( // ... 其他代码不变 <Select value={vehicleBodyId || ""} onChange={(e: any) => { // 只负责更新状态 setVehicleBodyId(e.value) }} options={generateBodyTypesOptions()} inputStyles={{ height: "60px", }} /> // ... 其他代码不变 ) }
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

