React中如何在setState状态更新完成后触发回调函数?
问题根因
- 写法错误:你当前代码中
setState(..., setCallback())是同步执行setCallback后将其返回值传递给setState,而非将setCallback本身作为回调注册,自然拿不到更新后的状态。 - API不匹配:函数组件中
useState返回的状态更新方法本身不支持传入回调参数,该用法仅适用于类组件的setState,函数组件中该写法不会生效。
可行解决方案
方案1:useEffect监听状态变化(最推荐)
将需要在状态更新后执行的逻辑放到useEffect中,把对应状态加入依赖数组,状态更新完成后会自动触发逻辑:
import { useState, useEffect } from 'react' const [state, setState] = useState(/* 初始值 */) const onClickCallback = () => { setState(/* 新值 */) } const setCallback = () => { console.log(state) // 此处打印的是更新后的最新状态值 if(state === something){ // 你的业务逻辑 } } useEffect(() => { setCallback() }, [state]) // 仅当state变化时触发执行
方案2:新增标识区分触发场景(仅部分状态更新需要执行逻辑时用)
如果不是所有state变化都需要执行回调,仅点击触发的更新才需要,可以新增辅助标识控制:
import { useState, useEffect } from 'react' const [state, setState] = useState(/* 初始值 */) const [isClickUpdate, setIsClickUpdate] = useState(false) const onClickCallback = () => { setState(/* 新值 */) setIsClickUpdate(true) } const setCallback = () => { console.log(state) if(state === something){ // 你的业务逻辑 } } useEffect(() => { if(isClickUpdate) { setCallback() setIsClickUpdate(false) // 执行完重置标识 } }, [state, isClickUpdate])
方案3:flushSync同步更新(非必要不推荐,会影响渲染性能)
React 18+可使用flushSync强制状态更新同步完成,之后直接调用回调即可拿到最新值:
import { useState } from 'react' import { flushSync } from 'react-dom' const [state, setState] = useState(/* 初始值 */) const onClickCallback = () => { flushSync(() => { setState(/* 新值 */) }) setCallback() // 此时状态已同步更新完成 } const setCallback = () => { console.log(state) // 最新状态值 if(state === something){ // 你的业务逻辑 } }
内容的提问来源于stack exchange,提问作者Etch
相关产品推荐
相关产品推荐

