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

