Me gustaría mostrar condicionalmente los errores en mi formulario.

La forma en que funciona formik es que si cambia un campo, se ejecutan todas las validaciones y se devuelven todos los errores, incluso aunque haya cambiado solo uno.

Me gustaría mostrar el error solo si el campo se TOCÓ y me gustaría que un campo se TOQUE al cambiar. El primer cambio en el campo debería hacerlo tocar.

Por el momento, formik está tocando campos solo al enviar. ¿Cómo podría tocarlo en Cambiar?

Esta es mi forma actual:

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
5
Lucian Tarna 10 sep. 2018 a las 15:41

3 respuestas

La mejor respuesta

Hola, creo que no es factible onChange, pero puede hacerlo cuando la entrada está borrosa y necesita usar la función handleBlur: onBlur={handleBlur}.

También los errores son un objeto que puede mostrar solo cuando un [input name] tiene uno.

Observe cuándo se ejecutan las validaciones aquí en los documentos: https : //jaredpalmer.com/formik/docs/guides/validation#when-does-validation-run

3
t3__rry 10 sep. 2018 a las 14:22

Para tocar un campo Formik en Cambiar, puede hacer esto:

<Formik
initialValues={initialValues}
onSubmit={(values) => {
    //submit form
}}>
{({ setFieldTouched, handleChange }) => {
    return (
        <Form>
            <Field
                name="type"
                onChange={e => {
                    setFieldTouched('type');
                    handleChange(e);
                }} />
        </Form>
    )
}}
4
Mudiaga Ejenavi 11 oct. 2019 a las 14:23

Una solución alternativa sería utilizar el método de formik getFieldMeta y pasar el nombre de su campo y llamar al valor prop que no es nulo cuando escribe algo.

errorMessage={
 formikProps.getFieldMeta("username").value
  ? formikProps.errors.username
   : ""
}
0
CLUTCHER 13 nov. 2019 a las 09:47