我有一个使用我的React应用程序中使用withFormik()
制作的表单的验证模式,这里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
文档,但是找不到适合我问题的东西。
就是这种情况,一次提交表单,然后在其中进行编辑,以便对多个字段中的一些进行细微调整。如果有多个字段并且仅编辑了一些字段,则我不想对所有存在的字段进行验证。
谢谢。
答案 0 :(得分:1)
我遇到了类似的问题,我最终创建了另一个字段,我在显示编辑屏幕时设置了该值。然后我在这样的测试函数中进行比较:
all.js
不完美,但绝对有效
答案 1 :(得分:0)
这是formik docs中所述的默认期望行为,但我认为您可以执行以下操作:
使用validate
函数代替使用validationSchema
。
验证功能将与您的validateSchema工作方式相同。您只需要通过带有mixed.validate
的函数以编程方式使用Yup因此,您可以完全控制表单中的所有道具。您还可以使用getFieldMeta
来获取字段的内容和值并将其用于验证。或者以touched
的形式从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
}
好吧,碰触可能不适用于您的用例,因为formik可能会在提交时将其设置为true,但是这里有所有道具,您可以使用其他内容,例如空值或您手动设置的其他状态道具。您在那里拥有所有控制权。