9

我想有条件地在我的表单中显示错误。

formik 的工作方式是,如果您更改一个字段,所有验证都会运行,并且即使您只更改了一个字段,也会返回所有错误。

我只想在字段被触摸并且我希望字段被触摸 onChange 时才显示错误。对字段的第一次更改应该使它被触及。

目前 formik 在提交时正在触及字段。我怎么能在改变时触摸它?

这是我目前的形式:

const optionsForSelect = (collection) => {
  return collection.map(item => ({
    value: item.id,
    label: item.name
  }))
}

const validationSchema = yup.object().shape({
  length: yup
    .number()
    .min(1, 'Length should be a positive non-zero integer')
    .required(),
  frame_rate: yup
    .string()
    .required()
})

class SpecificationsForm extends React.PureComponent {
  render() {
    const {
      values,
      handleChange,
      handleInputChange,
      handleSelectChange,
      handleBlur,
      errors,
      touched
    } = this.props;

    const debouncedHandleChange = debounce(handleChange, 200)

    console.log(errors)
    console.log('TOUCHED')
    console.log(touched)
    return (
      <div className="panel panel-default specifications-panel" id="js-turbosquid-product-specifications-panel">
        <div className="panel-heading">
          <a href="#" className="js-more-info" data-toggle="collapse" data-target="#specifications-panel-instructions" tabIndex="-1">
            Specifications
            <i className="fa fa-question-circle" />
          </a>
        </div>

        <div className="panel-body panel-collapse collapse in" id="specification-panel-body">
          <div className="panel-body-container">
            <div id="specifications-panel-instructions" className="panel-instructions collapse" />

            <div className="row">
              <div className="col-xs-6">

                <PanelInputField 
                  label='Length'
                  value={ values.length }
                  onChange={ (e) => handleInputChange(e, debouncedHandleChange) }
                  formName='turbosquid_product_form_length'
                  fieldName='length'
                />

                <div className="form-field-error">{errors.length ? errors.length : "No Error"}</div>

                <PanelSelectField
                  label='Frame Rate'
                  value={ values.frame_rate }
                  onChange={ ({value}) => handleSelectChange('frame_rate', value) } 
                  formName='turbosquid_product_form_frame_rate'
                  fieldName='frame_rate'
                  options={ optionsForSelect(frameRateDropdownData) }
                  searchable={ false }
                  clearable={ false }
                />
              </div>

              <div className="col-xs-6">

                <PanelCheckBox
                  label='Biped'
                  checked={ values.biped }
                  onChange={ (e) => handleInputChange(e, debouncedHandleChange) }
                  fieldName='biped'
                  formName='turbosquid_product_form_biped'
                />

                <PanelCheckBox
                  label='Loopable'
                  checked={ values.loopable }
                  onChange={ (e) => handleInputChange(e, debouncedHandleChange) }
                  fieldName='loopable'
                  formName='turbosquid_product_form_loopable'
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

const ProductSpecificationsMotionCapturePanel = withFormik({
  validationSchema,
  enableReinitialize: true,
  mapPropsToValues: (props) => (props),
  handleInputChange: (props) => (props.handleInputChange),
  handleSelectChange: (props) => (props.handleSelectChange),
})(SpecificationsForm)

export default ProductSpecificationsMotionCapturePanel
4

3 回答 3

12

要触摸 Formik 字段 onChange,您可以执行以下操作:

<Formik
initialValues={initialValues}
onSubmit={(values) => {
    //submit form
}}>
{({ setFieldTouched, handleChange }) => {
    return (
        <Form>
            <Field
                name="type"
                onChange={e => {
                    setFieldTouched('type');
                    handleChange(e);
                }} />
        </Form>
    )
}}

于 2019-10-11T14:23:12.307 回答
4

嗨,我认为这是onChange不可行的,但是当输入模糊并且您需要使用 handleBlur 函数时,您可以这样做:onBlur={handleBlur}

同样,错误是一个对象,您只能在给定对象有一个对象时显示它[input name]

查看文档中何时运行验证:https ://jaredpalmer.com/formik/docs/guides/validation#when-does-validation-run

于 2018-09-10T14:22:05.687 回答
0

一种解决方法是使用 formik 的方法getFieldMeta并传递您的字段名称并在您键入内容时调用不为空的 value 属性。

errorMessage={
 formikProps.getFieldMeta("username").value
  ? formikProps.errors.username
   : ""
}
于 2019-11-13T09:47:11.537 回答