React Formik + 是的,onChange 触摸字段

React Formik + Yup, onChange touch the field

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

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

我只想在该字段被 TOUCHED 时显示错误,并且我希望一个字段在更改时被 TOUCHED。该领域的第一个变化应该使它感动。

目前 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

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

还有错误是一个对象,你只能在给定的 [input name] 有一个对象时显示它。

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

要触摸 Formik 字段 onChange,您可以这样做:

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

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

errorMessage={
 formikProps.getFieldMeta("username").value
  ? formikProps.errors.username
   : ""
}