React Form Validation with Formik + Yup

Build a form with its validation in a simple way using Formik and Yup

Reza Mauliadi
JavaScript in Plain English

--

Creating a form validation is a tiring but yet important task. Building the form and its validation with the normal “React way” could be frustrating as you need to create the process from setting up states to form submission. Formik helps you to create a form in a simpler way. Along with Yup that provides a bunch of functions so you can make the validation process easier.

What will be covered in this article?

  1. Setting up form fields and initial values with Formik
  2. Handling user inputs
  3. Creating validation with Yup
  4. Handling form submission

In this article, I will show you how to build a simple signup page and handle the form validation. It consists of full name, email, password, and password confirmation fields.

1. Setting up fields and initial values with Formik

Here is an example of a signup form I have made.

As you can see, there is no state declared to store the value of the fields. We will not use the useState hook for that. Instead, we will use Formik to store the field values.

Before that, let’s install Formik.

npm install formik --save
// or
yarn add formik

Formik provides a custom hook that returns all the states and helpers needed, it called useFormik. It accepts an object that defines the configuration of the form.

We pass the initialValues for our form to the useFormik hook. The property names declared in the initialValues should match the name of the <input />. The returned states and helpers are now can be accessed from the formik variable. With that, we can. get the field values and put them on our input component: value={formik.values.full_name}. No need for React useState.

2. Handling user inputs

Next is catching the user input and store it in our Formik state. Formik provides us with a bunch of helper functions, one of them is handleChange. This function accepts the event object (that returned from the onChange) and uses the field name to store the value to the appropriate Formik state.

<input
type="text"
name="full_name"
value={formik.values.full_name}
onChange={formik.handleChange}
/>

There is no need to pass the field name to the handleChange as it will get the field name with event.target.name.

Handling user inputs is an easy job with Formik. With the handleChange function, we can just put it in all of our input’sonChange.

3. Creating validation with Yup

Setting up the form and handling user inputs are easy, validating the values is not. We must create the value checker to validate all of our fields. Thanks to Yup, we can make the validation process easier!

What is Yup? Quoting from the Yup documentation page: “Yup is a JavaScript schema builder for value parsing and validation”. We can use Yup to create a validation schema and pass it to the useFormik hook. Formik has an option for Yup called validationSchema.

First, let’s install Yup.

npm install yup --save
// or
yarn add yup

Then, we can import Yup on our page and create the validation schema for our form.

There are two things I have done above, i.e create the validation schema with Yup and show the error messages.

Create the validation schema with Yup

As you can see above, the schema is pretty straight forward. We just chain the validation function to create a set of validation schema. For example, we want our full_name value is not empty, is a string, has a minimum of 2 characters, and has a maximum of 15 characters. Then with Yup, we can use the required, string, min, and max functions. An error message also can be passed to each function.

More complex validations we usually meet is the email validation and password confirmation. Thankfully, Yup also provides us the functions to validate email and value equality. There are many more functions that Yup has. Detailed information about Yup can be found in its documentation page.

Show the error messages

The useFormik hook returns errors and touched states that can be used to show the error messages.

  • errors: an object of the form’s validation error.
  • touched: an object of boolean indicating if the field has been visited or not.

The Formik’s validation function runs on each keystroke of user inputs. It means that the errors object will contain all of the validation errors at any given moment. So, we can show an error message like this.

{formik.errors.full_name && <p>{formik.errors.full_name}</p>}

But this code will show the error message to the users immediately after they have typed something in a field. Normally, we want to show an error message after they have done typing in that field (not after the first character they typed). That’s why we need the touched state.

{formik.errors.full_name && formik.touched.full_name && (
<p>{formik.errors.full_name}</p>
)}

By checking the touched state, now we can show the error message after they have done with the field.

4. Handling form submission

To handle the form submission, we must pass an onSubmit option to the useFormik hook. We can access the submitted values within the onSubmit option function. You can do whatever you want with the values, such as use it as a payload to the API.

const formik = useFormik({
initialValues: {
...
},
validationSchema: Yup.object({
...
}),
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
}
});

The other helper function provided by Formik is handleSubmit. It will execute the onSubmit function we passed to useFormik if there are no errors from the validation. We can put the handleSubmit function on the <form>.

<form onSubmit={formik.handleSubmit}>

Here is the complete code of signup form and its validation with Formik and Yup.

Conclusion

With Formik + Yup, we can make the form validation easier. Formik provides us with a bunch of states and helpers to create a form. Then Yup provides us a complete set to create the validation schema.

Here is a working example of what we have discussed above.

Thanks!

--

--