Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

ReactJS Form Validation using Formik and Yup

  • Last Updated : 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 :

  1. String : Yup.string()
  2. Format as email (validation message) : Yup.email(“Invalid email address format”)
  3. Minimum characters : Yup.min(length , “Validation Message”)
  4. 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 .

  1. touched takes boolean values as input and it sets to true if a field is clicked.
  2. errors is used to display error messages set by the Yup object.
  3. isSubmitting is set to true after we click on submit form.
  4. 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: 




My Personal Notes arrow_drop_up
Recommended Articles
Page :