Redux-Forms used to be the goto library for validating and managing state for forms in React. The only issue was that adding redux can complicate things. Forms are normally self-contained and don’t require global management, you add multiple dependencies just to manage a simple form and testing can be difficult once you add redux. I have a previous tutorial on this here. In this tutorial, we’ll go over how to build a simple React form with validation using Formik. Click here for access to our video tutorials.

Adding Formik

The first step that you’ll need to do is add the Formik dependency as well as a validation library. You can create your own regex but you can also use a library like Yup to do the validation for you. Adding Reactstrap ad Bootstrap will be necessary for the UI.

yarn add formik yup reactstrap bootstrap

Make sure to add the bootstrap css to your index.js file.

import 'bootstrap/dist/css/bootstrap.min.css';

Creating Custom Input Field

Formik offer the option to use native html fields as well as customer JSX components as field components. When integrating with a library like Reactstrap, you can pass down props from Formik and use them with you component.

const customInputForm = ({field, form: {touched, errors}, ...props}) => (
    <div>
        <Input
            invalid={!!(touched[field.name] && errors[field.name])}
            {...field}
            {...props} />
        {touched[field.name] && errors[field.name] && <FormFeedback>{errors[field.name]}</FormFeedback>}
    </div>
);

Here you can see that field information as well as if the component has been touched or there are errors from validation are some of the props passed in. If there are errors, then a FormFeedback is displayed.

React Formik Validation

Validation is passed into Formik as a prop. You can use a validation schema created by Yup in order to target which fields are required, how long they should be and in what format.

const SignupSchema = Yup.object().shape({
  address: Yup.string()
    .min(2, "Too Short!")
    .max(50, "Too Long!")
    .required("Required"),
  password: Yup.string()
    .min(2, "Too Short!")
    .max(50, "Too Long!")
    .required("Required"),
  email: Yup.string()
    .email("Invalid email")
    .required("Required")
});

Now that we have our validation, we can use the custom input field inside of our form along with validation.

<Formik
                initialValues={{
                    email: '',
                    address: '',
                    password: ''
                }}
                validationSchema={SignupSchema}
                onSubmit={values => {
                    // same shape as initial values
                    console.log(values);
                }}>
              <Form>
                  <FormGroup>
                      <Label for="exampleEmail">Email</Label>
                      <Field name="email" type={'email'} component={customInputForm}/>
                  </FormGroup>
                  <FormGroup>
                      <Label for="address">Address</Label>
                      <Field name="address" type={'text'} component={customInputForm}/>
                  </FormGroup>
                  <FormGroup>
                      <Label for="examplePassword">Password</Label>
                      <Field name="password" type={'password'} component={customInputForm}/>
                  </FormGroup>
                  <Button>Submit</Button>
              </Form>
            </Formik>

When you run your app and touch the form elements without the proper inputs, you will get your validation errors.

React FormNeedsValidation

React FormNeedsValidation

If you enter in the correct information, you’ll then be able to Submit

React Validated Form

React Validated Form

Conclusion

Building React forms should not be overthought. It doesn’t require advanced state management and should be kept simple. Make sure to click below to gain access to videos on React and more.

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit