ReactJS Form Validation using Formik and Yup

20 Sep, 2021
As covered in the previous article, we can validate forms using controlled components. But it may be time-consuming and the length of the code may increase if we need forms at many places on our website. Here comes Formik and Yup to the rescue! Formik is designed to manage forms with complex validation with ease. Formik supports synchronous and asynchronous form-level and field-level validation. Furthermore, it comes with baked-in support for schema-based form-level validation through Yup. We would also use bootstrap so that we won’t waste our time on HTML and CSS.
Below is the step-by-step implementation on how to so Form Validation using Formik and Yup.
Step 1: Creating React Application And Installing Module:
npx create-react-app react-form
 
Step 2: After creating your project folder i.e.react-form , move to it using the following command:
cd react-form
Step 3: Then add bootstrap (this is optional if you want you can create your own styling).
yarn add bootstrap
Step 4: We can proceed to add Formik and Yup.
yarn add formik yup
Project Structure: It will look like the following.
project structure
Note: We will write down the entire code in the App.js file. Here, App is our default component where we have written our code. 
Step 5: <Formik> is a component that helps you with building forms. InitialValues is a prop that initializes all fields in your form. Generally, the initialization is an empty string but in some fields you may require an initial value.
Javascript
<Formik      initialValues={{        email: "",        password: ""      }}>
Step 6: We are adding a code block in which we are passing props provided by Formik and we are printing the props object on the console. Then we use the <Form> Component provided by Bootstrap in which we again pass 2 components namely <label> and <Field> Component. Lastly, we use the Bootstrap <Button> Component for submitting the form.  Basic boiler code of form component which should be wrapped inside formik.
Javascript
import React from "react";import { Formik, Form, Field } from "formik";  import "bootstrap/dist/css/bootstrap.css";  class App extends React.Component {  render() {    return (      <div className="container">        <div className="row">          <div className="col-lg-12">            <Formik initialValues={{ email: "", password: "" }}>              {(props) => (                <div>                  {console.log(props)}                  <div className="row mb-5">                    <div className="col-lg-12 text-center">                      <h1 className="mt-5">Login Form</h1>                    </div>                  </div>                  <Form>                    <div className="form-group">                      <label htmlFor="email">Email</label>                      <Field                        type="email"                        name="email"                        placeholder="Enter email"                        autoComplete="off"                      />                    </div>                      <div className="form-group">                      <label htmlFor="password" className="mt-3">                        Password                      </label>                      <Field                        type="password"                        name="password"                        placeholder="Enter password"                      />                    </div>                      <button                      type="submit"                      className="btn btn-primary btn-block mt-4"                    >                      Submit                    </button>                  </Form>                </div>              )}            </Formik>          </div>        </div>      </div>    );  }}  export default App;
Step 7: As discussed, we added a function that takes an argument (let’s say props) and we have wrapped our form inside the formik component and then we have printed the props argument so that we can see various props provided by formik. In the console, an object is displayed. If we look closely we can see that initial values also gets displayed in this object.
Step 8: Another prop for Formik is onSubmit which takes values as a parameter and it is mostly used for post api calls to collect the data out of the form and then we can store the data in the server. But in our case, we would keep it simple and just print the values in the console and alert a message. 
Javascript
<Formik    initialValues={{ email: "", password: "" }}    onSubmit={(values) => {      console.log(values)      alert("Form is validated and in this         block api call should be made...");      }    }>
Step 9: Also, here we can have validationSchema prop which takes the Yup object (in this case LoginSchema) as a parameter with customized validations like if we want our Field to be :
String : Yup.string()Format as email (validation message) : Yup.email(“Invalid email address format”)Minimum characters : Yup.min(length , “Validation Message”)Maximum characters : Yup.max(length , “Validation Message”)
String : Yup.string()
Format as email (validation message) : Yup.email(“Invalid email address format”)
Minimum characters : Yup.min(length , “Validation Message”)
Maximum characters : Yup.max(length , “Validation Message”)
Javascript
const LoginSchema = Yup.object().shape({  email: Yup.string()      // Format Validation    .email("Invalid email address format")      // Required Field Validation    .required("Email is required"),  password: Yup.string()      //Minimum Character Validation    .min(3, "Password must be 3 characters at minimum")    .required("Password is required")});
Step 10: Formik Component after including 3 props namely initialValues, ValidationSchema (to bind Formik and Yup), onSubmit looks like this : 
Javascript
<Formik    initialValues={{ email: "", password: "" }}    validationSchema={LoginSchema}    onSubmit={(values) => {    console.log(values)    alert("Form is validated! Submitting the form...");}}>
The 4 important states of props object are touched, errors , isSubmitting, values which are more than enough to create highly customized forms .
touched takes boolean values as input and it sets to true if a field is clicked.errors is used to display error messages set by the Yup object.isSubmitting is set to true after we click on submit form.values consist of all field values at that point in time.
touched takes boolean values as input and it sets to true if a field is clicked.
errors is used to display error messages set by the Yup object.
isSubmitting is set to true after we click on submit form.
values consist of all field values at that point in time.
Step 11: Now comes the ErrorMessage Component which we generally use below the Field Component to display the validation generated by Yup. We can add bootstrap class invalid-feedback for styling.
Javascript
<label htmlFor="email">Email</label>  <Field  type="email"  name="email"  placeholder="Enter email"  autocomplete="off"  className={`mt-2 form-control ${touched.email         && errors.email ? "is-invalid" : ""}`}   // If there is validation error then   // is-invalid bootstrap class is added/>  <ErrorMessage  component="div"  name="email"  className="invalid-feedback"/>
Step 12: We haven’t used isSubmitting prop in the function just yet. We can do one interesting thing using it. We can acknowledge the user who has been logged in and display his username and password using the values parameter on the screen by using conditional rendering and ternary operator.
Javascript
isSubmitting ? (<h1>Login Page</h1>) : (<h1>Confirmation of Login</h1>)// (condition) ? (if true this component gets displayed) :                 (else this component gets displayed)
Now we will see the complete code of the above steps.
App.js
import React from "react";import { Formik, Form, Field, ErrorMessage } from "formik";import * as Yup from "yup";import "bootstrap/dist/css/bootstrap.css";  const LoginSchema = Yup.object().shape({  email: Yup.string()    .email("Invalid email address format")    .required("Email is required"),  password: Yup.string()    .min(3, "Password must be 3 characters at minimum")    .required("Password is required"),});  class App extends React.Component {  render() {    return (      <div className="container">        <div className="row">          <div className="col-lg-12">            <Formik              initialValues={{ email: "", password: "" }}              validationSchema={LoginSchema}              onSubmit={(values) => {                console.log(values);                alert("Form is validated! Submitting the form...");              }}            >              {({ touched, errors, isSubmitting, values }) =>                !isSubmitting ? (                  <div>                    <div className="row mb-5">                      <div className="col-lg-12 text-center">                        <h1 className="mt-5">Login Form</h1>                      </div>                    </div>                    <Form>                      <div className="form-group">                        <label htmlFor="email">Email</label>                        <Field                          type="email"                          name="email"                          placeholder="Enter email"                          autocomplete="off"                          className={`mt-2 form-control                          ${touched.email && errors.email ? "is-invalid" : ""}`}                        />                          <ErrorMessage                          component="div"                          name="email"                          className="invalid-feedback"                        />                      </div>                        <div className="form-group">                        <label htmlFor="password" className="mt-3">                          Password                        </label>                        <Field                          type="password"                          name="password"                          placeholder="Enter password"                          className={`mt-2 form-control                          ${                            touched.password && errors.password                              ? "is-invalid"                              : ""                          }`}                        />                        <ErrorMessage                          component="div"                          name="password"                          className="invalid-feedback"                        />                      </div>                        <button                        type="submit"                        className="btn btn-primary btn-block mt-4"                      >                        Submit                      </button>                    </Form>                  </div>                ) : (                  <div>                    <h1 className="p-3 mt-5">Form Submitted</h1>                      <div className="alert alert-success mt-3">                      Thank for your connecting with us. Here's what we got from                      you !                    </div>                    <ul className="list-group">                      <li className="list-group-item">Email: {values.email}</li>                      <li className="list-group-item">                        Password: {values.password}                      </li>                    </ul>                  </div>                )              }            </Formik>          </div>        </div>      </div>    );  }}  export default App;
Step to Run Application: Run the application using the following command from the root directory of the project:
npm start
Output: Now open your browser and go to http://localhost:3000/, you will see the following output: 
Blogathon-2021
React-Questions
Blogathon
ReactJS
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Import JSON Data into SQL Server?
SQL Query to Convert Datetime to Date
Python program to convert XML to Dictionary
Scrape LinkedIn Using Selenium And Beautiful Soup in Python
How to toggle password visibility in forms using Bootstrap-icons ?
How to fetch data from an API in ReactJS ?
Axios in React: A Guide for Beginners
How to redirect to another page in ReactJS ?
ReactJS Functional Components