React Form Validation with Formik and Yup

React Form Validation with Formik and Yup

Hey everyone, in today's article we're going to explore a new topic related to forms in react also it is our job to ensure that when users interact with the forms we set up, the data they send across the form we except. This is what we're going to see how to handle form validation and track the state of forms without the aid of a form library. Next, we will see how the Formik library works. We'll learn how it can be implemented in our react app and how helpful it is to work with react forms validation. So, Let's start!

Form validation in React On its own, React is powerful enough for us to be able to set up custom validation for our forms. Let's see how to do that. We'll first start by creating our first form component with initial state. The following codesandbox explains the code of our custom forms:

Form validation with the use of a library, With the usestate hook, we set variables for the formValues, formErrors and isSubmitting.

  • The formValues variables holds the data the user puts into the input fields.
  • The formErrors variables holds the errors for each input.
  • The isSubmitting variable is a boolean that tracks if the form is being submitted or not, This will be true only when there are errors in the form.

Here, we have 4 form handlers and a useEffect hook to set up handle functionality of our form.

handleChange This keeps the inputs in sync with the formValues state and updates the state as the user types.

validate We pass in the formValues object as a argument to this function, then based on the email and password meeting the validation tests, the errors object is populated and returned.

handleSubmit Whenever the form is submitted, the formErrors state variable is populated with whatever errors may exist using the setFormErrors(validate(formValues)) method.

useEffect Here, we check if the formErrors object is empty, and if isSubmitting is true. If this check holds true, then the submitForm() helper is called. It has single dependency, which is the formErrors object. This means it only runs when the formErrors object changes.

submitForm: this handles the submission of the form data.

Here, we pass in the handleChange helper functions to the inputs' onChange attribute. We link the value of the inputs to the formValues object, making them controlled inputs. From the React docs, controlled inputs are inputs whose values are controlled by React. An input-error style is applied if there are any errors related to that specific input field. An error message is conditionally displayed beneath each input if there are any errors related to that specific input field.

Finally, we check if there are any errors in the errors object and if isSubmitting is true. If these conditions hold true, then we display a message notifying the user that they signed in successfully. With this, we have a fully functional and validated form set up without the aid of a library. However, a form library like Formik with the aid of Yup can simplify the complexities of handling forms for us.

What are Formik and Yup? Straight from the docs: "Formik is a small library that helps you with the 3 most annoying parts in handling forms:

  1. Getting values in and out of form state.
  2. Validation and error messages
  3. Handling form submission Formik is a flexible library. That allows you to decide even when and how much you want to use it. We can control how much functionality of the formik library we use. It can be used with HTML input fields and custom validation terms, or Yup and the custom components it provides.

Formik makes form validation so easy! When paired with Yup, they abstract all the complexities in smooth handling in react. Yup is a JavaScript object schema validator that have some great features , we'll see how it helps us to create custom validation rules. This is a sample Yup object schema validator or a sign up form. We'll go into Yup and how it works now! Let's see. Formik, HTML Input Fields And Custom Validation Rules

The following sandbox holds the code for this form set up:

The first thing we have to do is install Formik. Then we can go ahead to import it in the file where we'll make use of it. Before creating the component, we need to create an initialValues and validate object which we'll pass as props to the Formik component when we set it up. initialValues and validate are code snippets, not normal words. The decision to do this outside the component is not a technical one, but rather for readability of our code.

initialValues: is an object that describes the initial values of the respective form fields. The name given to each key in the initialValues must correspond with the value of the name of the input field we want Formik to watch. validate: this accepts a function that handles the form validation. The function accepts an object in the form of data values as an argument and validates each property in the object based on the rules defined. Each key in the values object must correspond with the name of the input field. onSubmit: This handles what happens after the user submits. The onSubmit prop takes a callback function that will only run when there are no errors, meaning the user inputs are valid. We pass in the initialValues object, and the submitForm and validate functions we defined earlier into Formik's initialValues, onSubmit and validate props respectively. Using the render props pattern, we have access to even more props the Formik API provides. values This holds the values of the user inputs. handleChange This is the input change event handler. It is passed to the input field . It handles the changes of the user inputs. handleSubmit The form submission handler. It is passed into the form

. This fires the function passed into the onSubmit prop whenever the form is submitted.

errors This object holds the validation errors that correspond to each input field, and is populated with the definitions we passed into the Yup object schema. touched This is an object that watches if a form field has been touched. Each key corresponds to the name of the input elements and has a boolean value. handleBlur This is the onBlur event handler, and it is passed to the input field . When the user removes focus from an input, this function is called. Without it, if there are any errors in the input when it loses focus, the errors will only display when the user tries to submit. isValid Returns true if there are no errors (i.e. the errors object is empty) and false otherwise. dirty This prop checks if our form has been touched or not. We can use this to disable our submit button when the form loads initially.

When the form is submitted, Formik checks if there are any errors in the errors object. If there are, it aborts the submission and displays the errors. To display the span using HTML inputs, we conditionally render and style the error message of each respective input field if the field has been touched and there are errors for that field. Also, we can add a visual cue to the button. The button is conditionally styled and disable it if there are errors in the errors object using the isValid and the dirty props. Validation Using Formik's Components And Yup # This sandbox holds the final code for this setup. We install Yup, import the Field, Form, and the ErrorMessage components from Formik. Formik makes form validation easy! When paired with Yup, they abstract all the complexities that surround handling forms in React. With that we can then go ahead to create the schema we'll be using for the sign in form using Yup. Instead of creating custom validations for each possible input field, which can be tedious, depending on the number of fields there are, we can leave that to Yup to handle. Yup works similarly to how we define propTypes in React. We created an object schema with Yup's object function. We define the shape of the validation object schema and pass it into Yup's shape() method. The required() method. This method takes a string as an argument, and this string will be the error message. that displays whenever a required field is left blank. This schema has two properties: An email property that is a string type and is required. A password property that is of number type but is not required.

We can chain validation is Yup as seen above. The properties of the schema object match the name of the input fields. The docs go into the different validation methods available in Yup. While using HTML input fields get the job done, Formik's custom components make things even easier for us, and reduce the amount of code we have to write! What are these custom components Formik provides us? Formik We've been using this for a while now. This is required for the other components to be usable. Form A wrapper that wraps the HTML

element. It automatically links the onSubmit method to the form's submit event. Field In the background, this automatically links the form input's onChange, onBlur and value attributes to Formik's handleChange, handleBlur, and values object respectively. It uses the name prop to match up with the state and automatically keeps the state in sync with the input value. With this component, we can decide to display it as an input field we want using it's as property. For example, will render a textarea. By default, it renders an HTML input field. ErrorMessage It handles rendering the error message for its respective field based on the value given to the name prop, which corresponds to the 's name prop. It displays the error message if the field has been visited and the error exists. By default, it renders a string is the component prop is not specified.

We pass the signInSchema into Formik using the validationSchema prop. The Formik team loves the Yup validation library so they created a specific prop for Yup called validationSchema which transforms errors into objects and matches against their values and touched functions.

Conclusion Users do not know or care how you handle form validation. However, for you the developer, it should be as painless a process as possible, and I believe Formik stands out as a solid choice in that regard. We have successfully looked at some of the options available to us when validating forms in React. We have seen how Formik can be used incrementally, and how it pairs well with Yup in handling form validation.

Did you find this article valuable?

Support Darshan Mandade by becoming a sponsor. Any amount is appreciated!