对于使用 withFormik()
制作的表单,我有这个验证模式在我的 React 应用程序中使用,这里 validateJql()
是我对 yup
的自定义验证函数
validationSchema: Yup.object().shape({
rework: Yup.string().required("Rework query is required").validateJql(),
originalEstimate: Yup.string().required("Original Estimate query is required").validateJql()
})
我的表单组件是这样的:
const addSomeForm = (props) => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleSubmit,
} = props;
return (
<form onSubmit={handleSubmit}>
<div className="form-group">
<div>
<label htmlFor="name" className="col-form-label"><b>Rework Query:</b></label>
<textarea id="query.rework" rows="5" type="text" className="form-control" placeholder="Enter JQL with aggregate Function" value={values.query.rework} onChange={handleChange} required />
{errors.query && errors.query.rework && touched.query && <span className="alert label"> <strong>{errors.query.rework}</strong></span>}
</div>
</div>
<div className="form-group">
<div>
<label htmlFor="name" className="col-form-label"><b>Original Estimate:</b></label>
<textarea id="query.originalEstimate" rows="5" type="text" className="form-control" placeholder="Enter JQL with aggregate Function" value={values.query.originalEstimate} onChange={handleChange} required />
{errors.query && errors.query.originalEstimate && touched.query && <span className="alert label"> <strong>{errors.query.originalEstimate}</strong></span>}
</div>
</div>
</form>
)
现在,如果字段
rework
,我想要做的不是在表单提交上运行验证。和 originalEstimate
不为所动,亦不为空。如何通过 withFormik
实现此目的? HOC 或 Yup
?我已经部分经历了Yup
文档和 Formik
docs,但找不到适合我的问题的东西。在提交一次表单并在此之后进行编辑以对其中一些字段进行细微调整后就是这种情况。如果有多个字段并且只编辑了一些字段,我不想对所有存在的字段进行验证。
先感谢您。
最佳答案
这是 formik docs 中所述的默认行为。但我认为您可以执行以下操作:
而不是使用 validationSchema
, 使用 validate
功能。
Validate 函数的工作方式与您的 validationSchema 工作方式相同。您只需要通过 mixed.validate 的函数以编程方式使用 Yup
因此,您可以完全控制表单中的所有 Prop 。您也可以使用 getFieldMeta
获取字段的值和值,并在您的验证中使用它。或者从 touched
获取这些 Prop 带有 getIn
的表单中的对象
就像是:
// Some util functions
function mapYupErrorsToFormikErrors(err: { inner: any[] }) {
return err.inner
.filter((i: { path: any }) => !!i.path)
.reduce(
(curr: any, next: { path: any; errors: any[] }) => ({
...curr,
[next.path]: next.errors[0],
}),
{},
)
}
function validateSchema(values: object, schema: Schema<object>) {
return schema
.validate(values, {
abortEarly: false,
strict: false,
})
.then(() => {
return {}
})
.catch(mapYupErrorsToFormikErrors)
}
// Your validation function, as you are using `withFormik` you will have the props present
function validateFoo(values, props) {
const { touched, value } = props.getFieldMeta('fooFieldName') // (or props.form.getFieldmeta, not sure)
const errors = validateSchema(values, yourYupSchema)
if (!touched && !value && errors.fooFieldName) {
delete errors.fooFieldName
}
return errors
}
好吧,touched 可能不适用于您的用例,因为 formik 可能会在提交时将其设置为 true,但是您拥有所有 Prop ,并且您可以使用不同的东西,例如空值或您手动设置的其他状态 Prop 。你在那里得到了所有的控制。
关于javascript - 如果字段不为空,请勿在提交时验证 Formik 和 Yup 中未触及的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54473643/