DEV Community

Jesse Ilc
Jesse Ilc

Posted on

How to Use Formik and Yup in Your React Project

For my TLDR people skip to the TLDR section.

Intro

Forms in React can be complex and tedious especially when working with controlled forms. Controlling state, adding validations, and handling submits can be a hassle when you have multiple form entries. Thankfully, libraries like Formik and Yup can help you add these features in a way that's simple and clean. So, let’s talk about how to use them.

Formik
“Formik is a popular open-source library for building and processing form data in React applications” – freecodecamp.org

Yup
“Yup is a schema builder for runtime value parsing and validation” – npmjs.com

Set up

1. Set up your React Project
I’m assuming most of you are already past this step but if not, you want to create your React project. You can follow along with the docs here, it’s fairly simple and straightforward.

2. Installing Formik and Yup
To install formik and yup, you just need to run the command in your terminal: npm install formik yup. Once those dependencies finish installing you’re pretty much ready to use them.

3. Create a form
Once again, I’m assuming most of you are already passed this step. But just in case, here is a link to a great tutorial on how to make React controlled forms.

Using Formik and Yup

1. Import Formik
At the top of the React component you want to use Formik in, you need to import it before you can use Formik.

import React from 'react';
import { useFormik } from 'formik';

const MyForm = () => {
// Your form logic will go here
};

export default MyForm;
Enter fullscreen mode Exit fullscreen mode

2. Import Yup
For Yup we have 2 different options. Since Yup helps with data validation it creates a schema. We can write this schema in the same component or we can write it in another file and import it. Both have their pros and cons but in general if you have multiple schemas it’s probably in your best interest to create a separate file. To do this, you first want to create a new folder in your src folder called schemas. In your schemas folder you want to create a JSX file (most people would just call it index.jsx). In your index.jsx file, you want to import Yup just like this: import * as yup from 'yup'. We don’t have schemas yet but we’ll cover that later when it becomes applicable.

Application

1. Prefix
For demonstration, I’m going to make a simple sign up form which includes a username and password. In your project you can build upon these ideas no matter how many inputs your form has. Here is what my form would look like if I were to build it in React without formik or yup:

import React, { useState } from "react";

function SignupForm () {
    const [username, setUsername] = useState("")
    const [password, setPassword] = useState("")

    function handleSubmit(e) {
        e.preventDefault();
        fetch(//your promise)
    }   

    return (
        <form autoComplete="off" onSubmit={handleSubmit}>
            <label>Username</label>
            <input 
                type="text"
                id="username"
                placeholder="Enter your username..."
                value={username}
                onChange={(e) => setUsername(e.target.value)}
            />
            <label>Password</label>
            <input 
                type="password"
                id="password"
                placeholder="Enter your password..."
                value={password}
                onChange={(e) =>setPassword(e.target.value)}
            />
            <button type="submit">
                Signup
            </button>
        </form>
    )
};

export default LoginForm;
Enter fullscreen mode Exit fullscreen mode

2. Creating a Schema
In our index.jsx file we created in the schema folder, let’s first create a schema or some validations we want to use in our form. Our file should look like this:

import * as yup from "yup"
Enter fullscreen mode Exit fullscreen mode

To define our schema we want to type this:

export const schema = yup.object().shape({})
Enter fullscreen mode Exit fullscreen mode

export will allow us to export this schema to any component it’s needed. Inside .shape({}) we are going to define our validations. Here is a simple validation schema:

export const schema = yup.object().shape({
    username: yup.string("Please enter a valid name").required("Required"),
    password: yup.string().min(5).required("Required"),
})
Enter fullscreen mode Exit fullscreen mode

For username we are saying that it needs to be a string with .string() and it cannot be empty (or null) with .required(). Inside of those methods we type an error message as a string.
For password we are once again saying that it needs to be a string with .string and it cannot be empty (or null) with .required(). We also state that the password needs to be a minimum length of 5.

Our index.jsx will look something like this:

import * as yup from "yup"

export const basicSchema = yup.object().shape({
    username: yup.string("Please enter a valid name").required("Required"),
    password: yup.string().min(5).required("Required"),
})
Enter fullscreen mode Exit fullscreen mode

3. Incorporating Formik
To use formik we declare it as so:

const formik = useFormik({}) 
Enter fullscreen mode Exit fullscreen mode

We can destructure formik to access certain elements. First let’s focus on state management. Let’s destructure our formik variable:

const { values, handleChange, handleSubmit } = useFormik({}) 
Enter fullscreen mode Exit fullscreen mode

There are more elements, but these are the basic ones we need. For state management, we no longer need useState. It’s now replaced by values and handleChange. Let's make our values:

const { values, handleChange, handleSubmit} = useFormik({
    initialValues: {
        username: "",
        password: "",
    },
})
Enter fullscreen mode Exit fullscreen mode

Then change our form as so:

<label>Username</label>
<input 
    type="text"
    id="username"
    placeholder="Enter your username..."
    value={values.username}
    onChange={handleChange}
/>
<label>Password</label>
<input 
    type="password"
    id="password"
    placeholder="Enter your password..."
    value={values.password}
    onChange={handleChange}
/>
Enter fullscreen mode Exit fullscreen mode

After we handle state management we need to add our schema here. Since we created a separate file, all we have to do is import and call it for the validationSchema:

import { basicSchema } from '../schemas'
// our component 
const { values, handleChange, handleSubmit} = useFormik({
    initialValues: {
        username: "",
        password: "",
    },
    validationSchema: basicSchema,  
})
Enter fullscreen mode Exit fullscreen mode

Now let's add onSubmit function underneath validationSchema:

// our component 
const { values, handleChange, handleSubmit} = useFormik({
    initialValues: {
        username: "",
        password: "",
    },
    validationSchema: basicSchema, 
    onSubmit: (values) => {
    fetch(// your promise)
    },
})
Enter fullscreen mode Exit fullscreen mode

You could also keep the onSubmit function separate like this:

const onSubmit = (values) => {
    fetch(// your promise)

const { values, handleChange, handleSubmit} = useFormik({
    initialValues: {
        username: "",
        password: "",
    },
    validationSchema: basicSchema, 
    onSubmit,
})
Enter fullscreen mode Exit fullscreen mode

Conclusion

Formik and Yup are great tools to help make React forms more responsive and easier to manage. With state management, validations, and a cleaner syntax they can help enhance your project. For more information on Formik or Yup check out the documentation.

TDLR

//imports
import React from "react";
import { useFormik } from 'formik';
import { basicSchema } from '../schemas';

//form component
function SignupForm() {

//formik 
    // declare and destucture 
    const { values, handleChange, handleSubmit} = useFormik({
        // setup values
        initialValues: {
            username: "",
            password: "",
        },
        // setup schema/validation
        validationSchema: basicSchema, 
        // submit function
        onSubmit: (values) => {
            fetch(// your promise)
        },
    })
    //form
    return (
        <label>Username</label>
        <input 
            type="text"
            id="username"
            placeholder="Enter your username..."
            value={values.username}
            onChange={handleChange}
        />
        <label>Password</label>
        <input 
            type="password"
            id="password"
            placeholder="Enter your password..."
            value={values.password}
            onChange={handleChange}
        />
    )
}

//schemas folder => index.jsx 
import * as yup from "yup"

//schema for formik
export const basicSchema = yup.object().shape({
    // add validation for each value
    username: yup.string("Please enter a valid name").required("Required"),
    password: yup.string().min(5).required("Required"),
})

Enter fullscreen mode Exit fullscreen mode

Sources

Top comments (2)

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Nice explaination but Formik is not maintained by the developers now and the last release was out a year ago, it might be depreciated in future, i would recommend using "react-hooks-form", similar to formik and easy to use
Cheers🙌

Collapse
 
jesseilc123 profile image
Jesse Ilc

Thanks for letting me know!