DEV Community

Cover image for Form Validation Using Formik and Yup in React
Shubham Tiwari
Shubham Tiwari

Posted on

Form Validation Using Formik and Yup in React

Hello Guys today i am going to show you how to Validate Form in React using Formik and Yup.

Formik is a small library that helps you with the 3 most annoying parts:

Getting values in and out of form state
Validation and error messages
Handling form submission

By colocating all of the above in one place, Formik will keep things organized--making testing, refactoring, and reasoning about your forms a breeze

INSTALLATION -

npm install formik --save
Enter fullscreen mode Exit fullscreen mode

For easy validation schema , we will use Yup with Formik.

npm install yup --save
Enter fullscreen mode Exit fullscreen mode

We will create a form with Three input fields here - First Name , Last Name and Email as this is just a demo of Formik.

Let dive into the Code -

import React from 'react';
import {Formik,Form,Field} from 'formik';
import * as Yup from 'yup';

function FormikYup() {
    function validateEmail(value) {
        let error;
        if (!value) {
          error = 'Required';
        } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {
          error = 'Invalid email address';
        }
        return error;
      }

    const SignUpSchema = Yup.object().shape(
        {
            firstname: Yup.string()
            .min(5,'Should be 5 character long')
            .max(15,'should not exceed 15 characters')
            .required('Required'),

            lastname: Yup.string()
            .min(5,'Should be 5 character long')
            .max(15,'should not exceed 15 characters')
            .required('Required'),

            email:Yup.string()
            .email('invalid email address')
            .required('Required')
        }
    );
    return (
        <div>
            <Formik
            initialValues = {
                {
                firstname:'',
                lastname:'',
                email:''
                }
            }
            validationSchema = {SignUpSchema}
            onSubmit = {values => {
                alert(values);
            }}
            >
            { ({errors,touched}) => (
                <Form>
                 <Field name="firstname" />
                 {
                     errors.firstname && touched.firstname ? (<div>{errors.firstname}</div>) : null
                 }
                 <Field name="lastname" />
                 {
                     errors.lastname && touched.lastname ? (<div>{errors.lastname}</div>) : null
                 }
                 <Field name="email" validate={validateEmail} />
                 {
                     errors.email && touched.email ? (<div>{errors.email}</div>) : null
                 }
                 <button type="submit" className="btn btn-success">Submit</button>
                 </Form>
            )}

            </Formik>
        </div>
    )
}

export default FormikYup

Enter fullscreen mode Exit fullscreen mode

Working -

  1. First we have imported the Required Modules (Formik,Form,Field) from Formik and Yup from yup.

  2. Then we created a function for email validation , it has required and email checker validation that email is in correct format or not.

  3. Then we created our validation schema named as SignupSchema , which has validation for firstname , lastname and email

  4. These validations checks for minimum and maximum value for the first name and last name field and also required validation for empty input field.

  5. Then for email , it checks the required and email format validations that the email is in correct format or not.

  6. Then we use Formik component and inside it , first we have set the initial values for our input fields.

  7. Then we have set the validation schema to our SignupSchema which we have created above to check the validations.

  8. Then inside onSubmit , we simply used the alert to show the values.(You can do other things inside onSubmit as you wish)

  9. Then we used the Form component and inside it We used the Field component and provided the attribute name to each input uniquely so that, the validations schema can uniquely check all the input fields for validations.

  10. erros.firstname && touched.firstname is used to check that the validation conditions are fullfilled or not , if not fullfilled , then it will show the error message which is provided in the validation schema just below the input field in which the error is found and if there is not error , then the error message will be hidden.

  11. In the end , we have provided a button with submit value to submit the form.

If you find any mistake or wants to give any suggestion , please mention it in the comment section.

THANK YOU FOR READING THIS POST.

FORMIK FULL DOCUMENTATION - https://formik.org/docs/overview

Top comments (2)

Collapse
 
victorocna profile image
Victor Ocnarescu

Great article, I really enjoyed reading it! Me and my dev team always choose Formik & Yup for form handling. And I might have a suggestion that can make your code even more beautiful.

Instead of

<Form>
    <Field name="firstname" />
    {
     errors.firstname && touched.firstname ? (<div>{errors.firstname}</div>) : null
    }
</Form>
Enter fullscreen mode Exit fullscreen mode

why not create a new component that will handle the errors like so

<Form>
    <Field name="firstname" />
    <ErrorField name="firstname" />
</Form>
Enter fullscreen mode Exit fullscreen mode

The ErrorField component can access the useFormikContext hook for errors and touched states.

const ErrorField = (name) => {
    const { errors, touched } = useFormikContext();
    if (!errors[name] || !touched[name]) {
        return null;
    }

    return <div>{errors[name]}</div>
}
Enter fullscreen mode Exit fullscreen mode

Let me know what you think. Cheers!

Collapse
 
nduyvu1511 profile image
Vu

That's great