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
相关产品推荐
相关产品推荐

