You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Formik中setValues执行完成后触发自定义函数的实现方案

Formik setValues执行完成后触发自定义函数的实现方法

Formik的setValues没有提供和React原生setState一致的回调参数,目前有三种通用实现方案,可根据你的项目场景选择:

方案1:利用setValues返回的Promise实现(最接近原生setState回调效果)

Formik 2.x及以上版本中,setValues本身是异步函数,执行后会返回Promise,状态更新完成后Promise会自动resolve,你可以直接在await或then回调中执行自定义逻辑:

// 先保存更新前的companyName用于判断变更
const oldCompanyName = values.companyName

// await等待setValues执行完成,此时Formik的values已经更新
await setValues((prev) => ({
  ...prev,
  companyName: value.get('name') || prev.companyName,
  companyNumber: value.get('id') || prev.companyNumber,
}))

// 变更判断+异步逻辑执行
if (values.companyName !== oldCompanyName) {
  await yourAsyncFunction()
}

// 也可以用.then写法替代async/await
/*
const oldCompanyName = values.companyName
setValues((prev) => ({
  ...prev,
  companyName: value.get('name') || prev.companyName,
  companyNumber: value.get('id') || prev.companyNumber,
})).then(() => {
  if (values.companyName !== oldCompanyName) {
    yourAsyncFunction()
  }
})
*/

方案2:useEffect监听值变化(官方推荐、兼容性最好)

如果你的项目用的是Formik 1.x,或者需要和其他React逻辑对齐,直接监听对应字段的变化触发逻辑即可:

// 从Formik上下文或者render props中拿到最新values
const { values } = useFormikContext()

useEffect(() => {
  const runAsyncLogic = async () => {
    // 这里的逻辑会在companyName更新渲染完成后自动触发
    await yourAsyncFunction()
  }
  runAsyncLogic()
}, [values.companyName])

方案3:调用setValues前预判断变更

如果你的异步逻辑不需要等Formik状态更新完成才执行,也可以提前判断变更,逻辑更直接:

const newCompanyName = value.get('name')
const isCompanyNameChanged = newCompanyName && newCompanyName !== values.companyName

setValues((prev) => ({
  ...prev,
  companyName: newCompanyName || prev.companyName,
  companyNumber: value.get('id') || prev.companyNumber,
}))

if (isCompanyNameChanged) {
  await yourAsyncFunction()
}

注意:方案3的异步逻辑和setValues的状态更新是并行执行的,如果异步逻辑依赖更新后的Formik状态,不要用这个方案,优先选方案1或2。

内容的提问来源于stack exchange,提问作者Leff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:36:04