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

Formik Dirty校验与数据更新联动问题咨询:提交后Dirty状态未自动重置的解决方法

解决Formik Dirty校验与数据更新不同步的问题

我来帮你搞定这个Formik的dirty状态不重置的问题!咱们先理清楚问题出在哪:

Formik的dirty状态是通过当前values和初始化时的initialValues对比来判断的。你现在的情况是,提交后虽然用changeState更新了本地的store,但Formik初始化后并不会自动监听外部state的变化——它内部还保留着最初的initialValues。所以哪怕你更新了store,Formik还是拿旧的initialValues和当前values对比,自然会认为数据还是被修改过,dirty就一直是true。

接下来给你两个关键的修复步骤:

1. 开启Formik的enableReinitialize属性

这个属性会让Formik监测initialValues的变化,一旦initialValues(也就是你的store)更新,Formik就会重新初始化内部的基准值,这样dirty就会基于新的基准值来判断。

2. 调整状态更新的时机

别在按钮的onClick里调用changeState了,把状态更新放到Formik的onSubmit函数里。这样能确保提交逻辑完成后再更新本地状态,避免重复操作和时机混乱。

修改后的完整代码示例

const [store, setStore] = useState<UserDataType>({ 
  firstName: 'Artem', 
  lastName: 'Bugay', 
  email: '', 
  age: '', 
  country: '', 
  region: '', 
  placeOfWork: '', 
  occupation: '', 
});

// 可以去掉单独的changeState函数,直接在onSubmit里更新状态

return ( 
  <Styled.WrapperContainer> 
    <Styled.Container> 
      <GlobalStyled.Title>Your profile</GlobalStyled.Title> 
      <Formik 
        initialValues={store} 
        onSubmit={async (values) => {
          // 先执行你的提交逻辑,比如调用updateProfile接口
          await updateProfile(values);
          // 提交成功后再更新本地状态
          setStore(values);
        }}
        enableReinitialize // 关键:开启重新初始化
      > 
        {({ values, isSubmitting, handleChange, dirty }) => { 
          return ( 
            <GlobalStyled.FormFormik> 
              {console.log('dirty', dirty)} 
              <Styled.Field type="text" name="firstName" label="First Name" value={values?.firstName} onChange={handleChange} /> 
              <Styled.Field type="text" name="lastName" label="Last Name" value={values?.lastName} onChange={handleChange} /> 
              <Styled.Field type="email" name="email" label="Email" value={values?.email} onChange={handleChange} /> 
              ... 
              <Styled.ButtonAntd 
                data-testid="profile" 
                htmlType="submit" 
                disabled={!dirty || isSubmitting} // 加上isSubmitting防止重复提交
              > 
                Update 
              </Styled.ButtonAntd> 
            </GlobalStyled.FormFormik> 
          ); 
        }} 
      </Formik> 
    </Styled.Container> 
  </Styled.WrapperContainer> 
);

这样修改后,当你提交成功,store更新,Formik会因为enableReinitialize重新初始化,把新的store作为新的initialValues,此时values和initialValues完全一致,dirty就会自动重置为false,按钮也会变回禁用状态,完美解决你的问题!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:57:27