Formik结合react-query时isSubmitting状态不生效问题求助
Formik isSubmitting 状态不生效的原因及解决方法
问题根源
核心问题是异步操作流程处理错误:
createNewUser.mutate()是异步发起API请求的方法,但你的代码在调用它之后立刻执行了setSubmitting(false)和resetForm(),导致Formik的isSubmitting状态刚被设为true就瞬间变回false,按钮根本来不及展示加载状态。- 直接手动设
loading={true}能生效,是因为这个状态不会被立刻覆盖,而Formik的isSubmitting被你快速重置了。
解决方法
两种可靠的修正方式,核心都是等待mutation完成(成功或失败)后再更新Formik的提交状态:
方案1:利用React Query Mutation的回调函数
在调用mutate时传入onSuccess和onError回调,在这些回调里处理Formik的状态重置:
<Formik initialValues={{ username: username, password: password }} validateOnChange={false} validateOnBlur={false} onSubmit={(values, { setSubmitting, resetForm }) => { setSubmitting(true); createNewUser.mutate( { name: values.username, password: values.password }, { onSuccess: () => { resetForm(); setSubmitting(false); }, onError: () => { setSubmitting(false); // 可在此添加错误提示逻辑 } } ); }} > {/* 原有表单内容保持不变 */} </Formik>
方案2:使用mutateAsync结合async/await
将Formik的onSubmit改为异步函数,通过await等待mutation完成,再执行后续操作:
<Formik initialValues={{ username: username, password: password }} validateOnChange={false} validateOnBlur={false} onSubmit={async (values, { setSubmitting, resetForm }) => { setSubmitting(true); try { await createNewUser.mutateAsync({ name: values.username, password: values.password }); resetForm(); } catch (error) { // 处理提交失败逻辑,比如提示用户 console.log("提交失败", error); } finally { // 无论成功失败,都要重置提交状态 setSubmitting(false); } }} > {/* 原有表单内容保持不变 */} </Formik>
额外说明
- 两种方案均可解决问题,可根据代码习惯选择:若需在mutation回调中处理更多请求结果相关逻辑,方案1更灵活;若偏好线性异步代码流程,方案2更直观。
- 务必在错误分支也设置
setSubmitting(false),避免请求失败时按钮一直处于加载状态。
内容的提问来源于stack exchange,提问作者Dmitriy_kzn
相关产品推荐
相关产品推荐

