JavaScript中如何让两个useState的更新函数按顺序同步执行?
问题原因分析
React 中 useState 返回的状态更新函数是异步批量执行的,在同一个渲染周期内连续调用多个更新函数时,所有更新会被暂存,等当前同步代码全部执行完毕后才会统一触发重渲染、计算新状态。你当前的写法存在两个问题:
- 调用
setNumber后,当前作用域内的number还是本次渲染的旧值,所以setPage(number)拿到的永远是更新前的数值,导致page和number差1 - 函数式更新里写
prev => prev++是错误的:后置递增运算符会先返回原prev值再做自增,最终实际返回给状态的还是旧值,建议改为prev => prev + 1
解决方案
下面给出三种常用的实现方式,可根据实际场景选择:
方案1:直接复用计算后的新值
不需要依赖状态返回值,提前计算好要更新的数值,分别传给两个更新函数即可:
const [number, setNumber] = useState(0) const [page, setPage] = useState(0) // 提前计算新值 const newNumber = number + 1 setNumber(newNumber) setPage(newNumber)
这种方式逻辑最简单,适合更新逻辑简单、两个值强关联的场景。
方案2:用useEffect监听number变化自动同步page
如果page的更新逻辑和number强绑定,可以通过副作用监听number的变化,number更新后自动触发page的更新:
const [number, setNumber] = useState(0) const [page, setPage] = useState(0) // 监听number变化,自动同步page useEffect(() => { setPage(number) }, [number]) // 之后只需要调用setNumber即可,page会自动同步更新 setNumber(prev => prev + 1)
这种方式适合更新逻辑复杂、可能在多个地方修改number的场景,不需要每次修改number都手动写一遍page的更新逻辑。
方案3:合并为同一个状态
如果两个状态本来就是强绑定、永远同步更新的,没必要拆成两个useState,可以合并为一个状态对象,减少维护成本:
const [pagination, setPagination] = useState({number: 0, page: 0}) // 一次更新两个属性 setPagination(prev => { const newNumber = prev.number + 1 return { ...prev, number: newNumber, page: newNumber } })
这种方式适合多个联动状态的场景,避免出现状态不同步的问题。
内容的提问来源于stack exchange,提问作者hegonen
相关产品推荐
相关产品推荐

