React Hooks中如何保证setState更新完成后再调用后续函数
问题原因
React 的 setState 为异步批量更新机制,调用 setSomething(1) 后仅会将更新请求加入调度队列,不会立刻修改当前渲染闭包内的 something 变量,也不会立即触发组件重渲染。同一执行上下文中的后续代码(如你代码里的 getStuff())读取到的永远是当前渲染周期的旧状态值,所以会出现你遇到的问题。
解决方案
方案1:直接将新值作为参数传递
如果 getStuff 依赖的就是你刚设置的新值,不需要等待状态落地,可以直接把新值作为参数传入函数,是成本最低的方案:
useEffect(() => { console.log('query changed'); const newVal = 1; setSomething(newVal); getStuff(newVal); }, [props.match.params.query]) const getStuff = async (val) => { console.log(val) }
方案2:通过 useEffect 监听状态变化触发逻辑
如果必须等状态更新完成、组件重渲染后再执行 getStuff,可以单独新增监听 something 变化的副作用:
// 原有副作用仅负责更新状态 useEffect(() => { console.log('query changed'); setSomething(1); }, [props.match.params.query]) // 新增副作用:something 变化后自动执行逻辑 useEffect(() => { // 可根据需求加边界判断,避免初始化时不必要的执行 getStuff(); }, [something]) const getStuff = async () => { console.log(something) }
方案3:用 useRef 同步存储最新状态值
如果不想频繁传参、也不想新增过多副作用,可以用 useRef 同步保存状态的最新值,任意位置都能直接读取:
const [something, setSomething] = useState(0); const somethingRef = useRef(something); // 状态更新时同步更新 ref 存储的值 useEffect(() => { somethingRef.current = something; }, [something]) useEffect(() => { console.log('query changed'); setSomething(1); getStuff(); }, [props.match.params.query]) const getStuff = async () => { // 读取 ref 中存储的最新值 console.log(somethingRef.current) }
内容的提问来源于stack exchange,提问作者Shooting Stars
相关产品推荐
相关产品推荐

