如果字段不为空,请勿在提交时验证Formik和Yup中未修改的字段

时间:2019-02-01 05:55:46

标签: javascript reactjs ecmascript-6 formik yup

我有一个使用我的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>
    )

现在,我想做的是如果没有触摸reworkoriginalEstimate字段并且也不为空,则不要在表单提交上运行验证。如何使用withFormik HOC或Yup实现?我已经部分浏览过Yup文档和Formik文档,但是找不到适合我问题的东西。

就是这种情况,一次提交表单,然后在其中进行编辑,以便对多个字段中的一些进行细微调整。如果有多个字段并且仅编辑了一些字段,则我不想对所有存在的字段进行验证。

谢谢。

2 个答案:

答案 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,但是这里有所有道具,您可以使用其他内容,例如空值或您手动设置的其他状态道具。您在那里拥有所有控制权。