DEV Community

Cover image for How to use formik with useFormik prop in react
Aneeqa Khan
Aneeqa Khan

Posted on

How to use formik with useFormik prop in react

Formik is a super cool library and I use it every time. So today I am writing this post for beginners and it covers the use of formik on the simple login form.

I'll cover these things here

Create and style a login form

I created login form like this

      <form className="form">
        <div className="field">
          <label htmlFor="email">Email Address</label>
          <input
            id="email"
            name="email"
            type="email"
          />
        </div>
        <div className="field">
          <label htmlFor="password">Password</label>
          <input
            id="password"
            name="password"
            type="password"
          />
        </div>
        <button type="submit" className="submit-btn">
          Login
        </button>
      </form>
Enter fullscreen mode Exit fullscreen mode

and styled it like this

.form {
  width: 300px;
  display: flex;
  flex-direction: column;
  margin-top: 50px;
  background-color: #ddd;
  border-radius: 8px;
  padding: 10px;
}
.field {
  display: flex;
  justify-content: space-between;
  padding-bottom: 10px;
}
.submit-btn {
  align-self: flex-end;
  width: 80px;
}
Enter fullscreen mode Exit fullscreen mode

After this, you'll get a login form same as this
Alt Text

Initialize formik default states

Lets import the useFormik first from the formik

import { useFormik } from "formik";
Enter fullscreen mode Exit fullscreen mode

Now you can create a formik object using useFormik hook and define your initialValues in it

  const formik = useFormik({
    initialValues: {
      email: "",
      password: ""
    }
  });
Enter fullscreen mode Exit fullscreen mode

let's use the formik handleChange function and pass formik values to our input fields

     ...
          <input
            id="email"
            name="email"
            type="email"
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            value={formik.values.email}
          />
     ...
          <input
            id="password"
            name="password"
            type="password"
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            value={formik.values.password}
          />
Enter fullscreen mode Exit fullscreen mode

Apply validations on login fields

I used Yup library to apply validations on my fields. You can use custom regex as well if you don't want to use Yup for some reason.
So first import Yup like this

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

Then I added validationSchema for my login fields

 const formik = useFormik({
    initialValues: {
      email: "",
      password: ""
    },
    validationSchema: Yup.object().shape({
      email: Yup.string()
        .email("Invalid email address")
        .required("Please enter email"),
      password: Yup.string().required("Please enter password")
    }),
  });
Enter fullscreen mode Exit fullscreen mode

Here Yup is validating if the values of the field are provided; if yes, then is it correct format or not.
So if any error happens according to our validation schema, it will be stored in formik's errors object and we can print it beside or below the field like this

     {formik.touched.email && formik.errors.email ? (
         <span className="error">{formik.errors.email}</span>
     ) : null}
Enter fullscreen mode Exit fullscreen mode

Now our form looks like this with validation errors
Alt Text

Write submit form function

The last step is to create submit function and perform your operation on formik values. You can navigate to the next screen, call API, or anything you want to do. I just set a state on submit and shown a message to a user on the login

  const formik = useFormik({
    initialValues: {
      email: "",
      password: ""
    },
    validationSchema: Yup.object().shape({
      email: Yup.string()
        .email("Invalid email address")
        .required("Please enter email"),
      password: Yup.string().required("Please enter password")
    }),
    onSubmit: (values) => {
      setIsLoggedIn(true);
    }
  });
Enter fullscreen mode Exit fullscreen mode

and pass formik handleSubmit function to your form like this

<form className="form" onSubmit={formik.handleSubmit}>
Enter fullscreen mode Exit fullscreen mode

and here your form is ready with field validations!!
You can find the full source code here

Oldest comments (8)

Collapse
 
_genjudev profile image
Larson

Or just use required and type attribute.

Collapse
 
aiosifelisl1 profile image
Andreas Iosifelis

Maybe it's my lack of understanding but I don't understand why people create libraries that have nothing to offer. I don't understand what formik has to offer more than the native functionality of a browser. With all due respect.

Collapse
 
aneeqakhan profile image
Aneeqa Khan • Edited

I don't agree to "formik have nothing to offer". Because formik handles the low-level details for us like we no need to worry about handleBlur, handleFocus and handleChange of fields and also we don't need to create error states, etc. So I prefer it but if you like to work with native functionality then its good, it is totally your choice 🤗

Collapse
 
aiosifelisl1 profile image
Andreas Iosifelis

I agree, it's a matter of choice. Well said! =)

Collapse
 
florinandreas profile image
FlorinAndreas

Obviously you didn't had to deal with a lot of complicated forms in your life.
After you create all that by hand you can go back and look formik in depth. Only after you will appreciate that someone took the time to create it.

Collapse
 
wahbeangit profile image
wahbean-git

Formik allows nested values, e.g. user.email, to be easily used in forms.
React does not allow this with useState.

Collapse
 
vishakp profile image
Vishak P

How to implement nested form with useFormik?

Collapse
 
ramin profile image
Ramin Khodaie

Very useFull content, I used to work with and

tags of formik, but with the idea that this content gives me I start to seprate my jsx from logic using useFormik in another .ts files.