React TypeScript项目:加载Modal时禁用Formik验证求助
解决Formik模态框打开即显示验证错误的问题
问题根源
- Add按钮类型错误:设置为
type="submit",点击时直接触发Formik表单提交,执行验证逻辑 - Formik配置拼写错误:
validateOnsubmit应为validateOnSubmit,导致配置不生效 - Field的onBlur绑定错误:直接执行函数(
setRoleFieldState(values.role_category)),组件挂载时立即触发状态更新,间接触发验证 - 错误提示时机未控制:初始空值触发的验证错误未结合
touched/submit状态判断,直接显示
分步解决方案
1. 修正Add按钮类型
将Add按钮改为type="button",仅负责打开模态框,不触发表单提交:
<Button size="s" class="primary" name="Add" type="button" {/* 修改此处 */} disabled={false} onClick={() => { setId(undefined); setFieldValue("role_category", ""); setFieldValue("description", ""); toggleModal(); }} ></Button>
2. 修正Formik配置
确保属性名正确,仅在提交时触发验证:
<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit} validateOnMount={false} validateOnSubmit={true} {/* 正确拼写 */} validateOnChange={false} validateOnBlur={false} >
3. 修复Field的onBlur绑定
改为箭头函数延迟执行,避免组件挂载时触发:
<Field name="role_category" type="text" className="form-control" onBlur={() => setRoleFieldState(values.role_category)} {/* 修改为箭头函数 */} /> <Field name="description" type="text" className="form-control" onBlur={() => setDescriptionFieldState(values.description)} {/* 修改为箭头函数 */} />
4. 控制错误提示显示时机
结合Formik的touched状态和submitCount,仅当字段被触碰或表单提交过才显示错误:
{({ setFieldValue, values, touched, submitCount }) => ( <Form> {/* ...其他代码... */} <div className="form-group"> <label htmlFor="role_category">Role Category</label> <Field name="role_category" type="text" className="form-control" onBlur={() => setRoleFieldState(values.role_category)} /> {(touched.role_category || submitCount > 0) && ( <ErrorMessage name="role_category" component="div" className="alert yup-error" /> )} </div> <div className="form-group"> <label htmlFor="description">Description</label> <Field name="description" type="text" className="form-control" onBlur={() => setDescriptionFieldState(values.description)} /> {(touched.description || submitCount > 0) && ( <ErrorMessage name="description" component="div" className="alert yup-error" /> )} </div> {/* ...其他代码... */} </Form> )}
5. 复用Formik提交机制
移除Save按钮的自定义onClick,让Formik处理提交流程,确保验证通过后才执行保存:
<Button size="s" class="primary" name="Save" type="submit" disabled={roleFieldState === "" || descriptionFieldState === ""} ></Button>
在handleSubmit中处理保存逻辑:
const handleSubmit = async (values: typeof initialValues, { resetForm }) => { const roleValue = { role: values.role_category, des: values.description, }; await handleSave(roleValue); toggleModal(); resetForm(); // 可选:重置表单状态 };
6. 打开模态框时重置状态(可选)
确保每次打开模态框时表单状态干净,重置touched和submitCount:
// 先从Formik解构出resetForm {({ setFieldValue, values, touched, submitCount, resetForm }) => ( // ... <Button // ... onClick={() => { setId(undefined); resetForm({ values: initialValues, touched: {}, submitCount: 0, }); toggleModal(); }} ></Button> )}
额外优化建议
- 移除自定义的
roleFieldState和descriptionFieldState,直接使用Formik的values和touched状态,减少冗余 - 利用Formik的
handleBlur自动维护touched状态:
<Field name="role_category" type="text" className="form-control" onBlur={(e) => { handleBlur(e); // 更新Formik的touched状态 // 保留自定义逻辑(如果需要) }} />
内容的提问来源于stack exchange,提问作者Edi-nano
相关产品推荐
相关产品推荐

