React同一次渲染中更新state后能否用最新值更新另一个state
核心结论
首先明确:不能直接在同一次渲染周期内获取刚更新的state值。React的状态更新默认是批量异步处理的,调用state的setter方法后,当前渲染周期闭包内的state变量不会立即变更,必须等到下一次重渲染才会拿到更新后的值,所以你原来的写法中setTxt(num+1)拿到的永远是更新前的旧num值。
可行实现方案
你期望的效果是点击一次按钮后,num加1,txt基于更新后的num再加1(即首次点击后num=1、txt=2,第二次点击后num=2、txt=3,以此类推),可以用以下几种方案实现:
- 方案1:预先计算更新值,同时更新两个state
这是性能最优、逻辑最简单的方案,你可以先计算出num要更新的目标值,直接用这个值计算txt的目标值即可,不需要依赖state的更新结果:
handleClick = () => { const newNum = num + 1; setNum(newNum); setTxt(newNum + 1); }
- 方案2:用
useEffect监听num变化自动更新txt
如果txt的取值完全依赖num,且存在多处修改num的场景,可以用useEffect绑定两者的依赖关系,只要num变化就自动更新txt:
import "./styles.css"; import { useState, useEffect } from 'react'; export default function App() { const [num, setNum] = useState(0) const [txt, setTxt] = useState(0) // num变化时自动更新txt useEffect(() => { setTxt(num + 1); }, [num]) handleClick = () => { setNum(num + 1) } return ( <div className="App"> <input type="submit" value="button" onClick={handleClick} /> <h1>{num}</h1> <h1>{txt}</h1> </div> ); }
- 方案3:使用setter的函数式更新获取最新状态
如果需要在状态更新逻辑内部拿到最新的状态值,可以使用setter的函数式入参形式,函数的第一个参数就是当前最新的状态值:
handleClick = () => { setNum(prevNum => { const updatedNum = prevNum + 1; setTxt(updatedNum + 1); return updatedNum; }) }
内容的提问来源于stack exchange,提问作者Gautham Muralidharan
相关产品推荐
相关产品推荐

