gene b.
gene b.

Reputation: 11994

React-Bootstrap Example with Formik marks all error fields (even untouched) in Official Tutorial

In the Bootstrap-React Tutorial, I was reading the section on Form Validation, where they hook up Formik to demo their form validation: https://react-bootstrap.github.io/components/forms/#forms-validation-libraries

But if you notice in their demo, if you just touch one required field (e.g. "State") and start typing, all the form fields immediately are flagged as errors, even the ones you didn't touch.

I noticed they were doing isInvalid={!!errors.username} on the last several fields. Their FirstName/lastName use a different strategy: isValid={touched.lastName && !errors.lastName}. To test that, I made the initial values blank for FirstName/LastName,

      initialValues={{
        firstName: '',
        lastName: '',

to verify that they would flag on touched-only. But it stopped working, and doesn't flag required errors at all now. When I edit firstName/lastName to be blank, there's no error flagged, even though rules are defined on them:

  firstName: yup.string().required(),
  lastName: yup.string().required(),

The full code is on that page, this is just a snippet:

function FormExample() {
  return (
    <Formik
      validationSchema={schema}
      onSubmit={console.log}
      initialValues={{
        firstName: 'Mark',
        lastName: 'Otto',
        username: '',
        city: '',
        state: '',
        zip: '',
        terms: false,
      }}
    >
      {({
        handleSubmit,
        handleChange,
        handleBlur,
        values,
        touched,
        isValid,
        errors,
      }) => (
        <Form noValidate onSubmit={handleSubmit}>
          <Form.Row>

        <Form.Group as={Col} md="4" controlId="validationFormik02">
          <Form.Label>Last name</Form.Label>
          <Form.Control
            type="text"
            name="lastName"
            value={values.lastName}
            onChange={handleChange}
            isValid={touched.lastName && !errors.lastName}
          />                  

            <Form.Group as={Col} md="3" controlId="validationFormik04">
              <Form.Label>State</Form.Label>
              <Form.Control
                type="text"
                placeholder="State"
                name="state"
                value={values.state}
                onChange={handleChange}
                isInvalid={!!errors.state}
              />
              <Form.Control.Feedback type="invalid">
                {errors.state}
              </Form.Control.Feedback>
            </Form.Group>
            <Form.Group as={Col} md="3" controlId="validationFormik05">
              <Form.Label>Zip</Form.Label>
              <Form.Control
                type="text"
                placeholder="Zip"
                name="zip"
                value={values.zip}
                onChange={handleChange}
                isInvalid={!!errors.zip}
              />

Upvotes: 1

Views: 888

Answers (1)

gene b.
gene b.

Reputation: 11994

Looks like I found the answer: they don't have the necessary line

onBlur={handleBlur} /* This is necessary for 'touched' to be populated! */

on each control. The Blur handler is necessary for Formik to populate touched values. Their original code isn't populating touched properly.

Why isn't the Formik `touched` property being populated?

Upvotes: 1

Related Questions