João Miguel Cunha

@joomiguelcunha

Painless React Forms with Formik

formik logo

I’ve been with React since the start and one thing I always hated was how coding Forms and corresponding validation was a boring, sometimes difficult chore. It involved way too much work for it to pay off and it took even more work to centralize and make the code reusable.

Well, not anymore! 😃 ✨✨✨

I recently discovered Formik and the pain is gone!

Formik helps with the major problems of handling forms in React:

  1. Transforming props to form state
  2. Validation and error messages
  3. Handling form submission

For validation Formik uses yup, an amazing object schema validation/parsing library.

Let me walk you through a crash course of this amazing package.

Building a Form

First install the package, both Formik and Yup

yarn add formik yup

Let’s start building our form. It will consist of an imaginary user filling out his email, username and some imaginary thing out of a choice of many. Pretty standard form and you will see how easy it is.

Full final example here or below! 😄

working example

Our main file index.js:

index.js

Of course this is just a barebones example of a root file for demonstration purposes, but what I want to point out is that the imaginaryUser variable can come from wherever you’d like. Be it API, read from a file, whatever. We just need it’s default (or existing) values to map them into Formik.

So we see we have a user with a blank email, blank username and null for imaginaryThingId. Let’s take a look at our UserForm.js.

UserForm.js dependencies and variables

We first must get our Formik and Yup dependencies.

I use react-virtualized-select for select boxes with memoization for maximum performance of many items. We must also include the select box styles for the default look.

imaginaryThings is a just an array of options for the select box and they are declared like that for demonstration purposes. You can obtain them and pass them in however you’d like. They are already neatly formatted correctly for the select box.

We want something like this:

As we can see, it’s as simple as it can get. Required email, required username and an optional field. Let’s see how we can plug all this in.

By going through the form code you probably have realised that Formik is a HOC (Higher-Order-Component). It injects some handy props into your form component and you can go to town doing whatever you want with them!

In my example I’ve customized mapPropsToValues, validationSchema and handleSubmit.

mapPropsToValues: You can use this to simplify and “flatten” some nested object in order to make things easier to understand and work with.

validationSchema: This is where you define your form validation. Using Yup you can create simple and complex validation structures. I’ll present 2 complex examples later in this post.

handleSubmit: This is the submission handler for the form. It will only fire if the form is valid and you can do whatever you want in it. You want to do a flip, sing a song, go for sushi and then send data to the server?!

JUST DO IT

If you have fiddled around with my example you probably know the gist. The values props holds all the form values, errors (DUH!), touched and dirty hold the values of which an input has lost focus and user has interacted with the input respectively.

The functions I’m using are handleChange which works with the value and the inputs name (and if it doesn’t have name the id) and does the magic for you. If you need some extra work before the magic you can use setFieldValue that I used for setting the imaginaryThingId value. handleBlur handles the blur event of an input and runs validation. Finally handleSubmit that we plug straight into the onSubmit event of the form.

As you can see this is as easy as it can get. You don’t have to do a thing, Formik is a beast and does it all for you while giving you the tools do go beyond.

Let’s talk validation 👌 ✅ ❎

The documentation for Yup is AMAZING. You’ll probably find whatever you want in there. But, since I’m a nice guy I’ll throw in some examples of a complex form of validation.

Here are some dumbed down for demonstration purposes examples.

What if I want to validate the usernames length ONLY if the email is foobar@example.com?

JUST DO IT

We can see that when email is example@foobar.com we add the min rule to the schema. If not we just return the schema untouched!

What if I want to change the label of the error message depending on the condition?

JUST DO IT

Easy enough! Yup has .label for that purpose. Let’s see how!

As you can see when the condition is true the label switches in the error message for papidipupi. We can dos this dinamically by adding ${path} to whatever message we want. e.g: the required error message.

What if I want to run my own custom validation function?

JUST DO IT

For this we are going to use the test function which allows you to define a new test for that specific field.

Let’s see if we can specifically test that the username is (by no reasonable reason) zigzagging!

As we can see we just added a simple straightforward check!

We can go on and on but I think I’ve provided enough basics to intice you to use Formik and Yup! Both projects have great and extensive documentation so it’s mandatory you check it out.

More by João Miguel Cunha

Topics of interest

More Related Stories