DEV Community

Cover image for How to create better forms in react: with Formik and Yup.
Malissa Bishop
Malissa Bishop

Posted on

How to create better forms in react: with Formik and Yup.

What is Formik?

Formik is an open source library that allows us to deal with forms in React; without the headache. Usually, a form in react involves repetition and can cause an annoyance of errors, keeping track of values, and handling submissions. This makes getting data in and out of forms quite taxing. With Formik, we're able to spend less time dealing with state and onChange submissions.
Note: As a prerequisite, a basic understanding of React and some knowledge about forms is required.

What is Yup?

Forms are key in collecting data from users as they navigate and interact with our applications. In order to ensure this is done accurately and efficiently, we utilize form validation. This is where Yup comes in, a library that structures the expected data from the user and allows us to dictate if it's required or not. It helps us create custom validation rules, so we don't have to write them out from scratch. Later on in the article, we'll go into depth about how this actually works.

Follow along in your code editor so you can visually see the differences, and practice with forms of your own.

Install.

Now that we have an understanding of Formik and Yup, lets install them in our terminals, so we can start using them.

// with npm
npm install --save formik yup

// with yarn
yarn add formik
yarn add yup
Enter fullscreen mode Exit fullscreen mode

First things first, we'll create an app within the terminal, cd into it, and run 'npm start', so that we're able to see our app in the browser.

npx create-react-app my-app
cd my-app
npm start
Enter fullscreen mode Exit fullscreen mode

React Forms Vs. Formik & Yup

Below we'll see the use of React forms without Formik and Yup. So, I created a sign up form that requests the first name of a user. As a user types into the form, we want to store the data in our local state. We would have to implement useState and an onChange function, to capture what the user types into the form. In order to see this happening we can place a console.log of the 'firstName' and see the keystrokes as we type in our console.

import { React, useState } from 'react';


export default function SignupForm() {

    const [firstName, setFirstName] = useState("")
    const [lastName, setLastName] = useState("")
    console.log(firstName)

    return (
        <form>
            <div className='input-container'>
                <input 
                    id="firstName"
                    name="firstName"
                    type="text"
                    placeholder="First Name"
                    onChange={(e) => setFirstName(e.target.value)}
                    value={firstName}
                />
            </div>
<div className='input-container'>
                <input 
                    id="lastName"
                    name="lastName"
                    type="text"
                    placeholder="Last Name"
                    onChange={(e) => setLastName(e.target.value)}
                    value={lastName}
                />
            </div>
        </form>
    )
}
Enter fullscreen mode Exit fullscreen mode

Now imagine we needed more than just a first name, like a user's billing information or an entire survey. This can start to become daunting, as we would have to build out a 'useState' for each and every piece of information we're requesting from the user.

Formik & Yup to the rescue!

In order to use Formik, we have to import the hook. This is done in the same manner as 'useState'. We then declare a constant and set it equal to 'useFormik'. We set our initial values to empty strings; the name given to each key must match the value of the name we set in the input field. Formik has a built in 'handleChange' function to capture any change in data input; therefore, we are able to get rid of the 'onChange' arrow functions. We utilize dot notation 'formik.value' and attach whatever the key value represents. Handling submissions is also done with ease, as we create an 'onSubmit' function and place it within the form. This will handle what happens after the user submits, and will only run when there are no errors. This makes our code less verbose and more scalable.


import { useFormik } from 'formik';
import * as Yup from 'yup';


export default function SignupForm() {


    const formik = useFormik({
        initialValues: {
            firstName: "",
            lastName: ""
        },
        validationSchema: Yup.object({
            firstName: Yup.string()
            .max(2, "Must be 2 characters or less")
            .required("Required"),
            lastName: Yup.string()
            .min(10, "Must be 10 characters or more")
            .required("Required")
        }),
        onSubmit: (values) => {
            console.log(values);
        }
    })

    return (
        <form onSubmit={formik.handleSubmit}>
            <div className='input-container'>
                <input 
                    id="firstName"
                    name="firstName"
                    type="text"
                    placeholder="First Name"
                    onChange={formik.handleChange}
                    onBlur={formik.handleBlur}
                    value={formik.values.firstName}
                />
                {formik.touched.firstName && formik.errors.firstName ? <p>{formik.errors.firstName}</p> : null}
            </div>
            <div className='input-container'>
                <input 
                    id="lastName"
                    name="lastName"
                    type="text"
                    placeholder="Last Name"
                    onChange={formik.handleChange}
                    onBlur={formik.handleBlur}
                    value={formik.values.lastName}
                />
                {formik.touched.lastName && formik.errors.lastName ? <p>{formik.errors.lastName}</p> : null}
            </div>
            <button type='submit'>Submit</button>
        </form>
    )
}
Enter fullscreen mode Exit fullscreen mode

Yup!

Need some form validation, that happens to also double as error handling? If your answer was Yup!, look no further, like mentioned above Yup is a library that handles our form validations and error handling. First, we'll create an object schema with Yup's 'object' function. Then, pass in our input fields and tack on the expected data type, which in this case is a string. The '.required' method is a parameter we can set, as well as the error message we want displayed whenever that field is left blank. Pretty handy right! Lastly, we implement a ternary operation to show if a user doesn't click within the form, do not show error messages or require that they follow the constraints we set. Yup and Formik's api has many useful functions that do most of the work for us, such as onBlur. This activates the form validation and error handling, so a user submits valid data.

Conclusion.

As developers, Formik paired with Yup, save us time and allow us to easily validate forms in react. Not saying we couldn't without these libraries, but doing so with dry, scalable code in half the time is a win-win!

Resources

Here's some resources to further research these libraries.

Top comments (0)