Formik is a form management library that provides components and hooks to ease the process of creating React forms. Formik takes care of form states, validation, and error handlers for you which makes it easy to collect and store user data.

In this tutorial, you will learn how you can create a registration form in React using Formik. To follow along, you should be comfortable working with React hooks.

Create a React App

Use create-react-app to create a new React project:

        npx create-react-app formik-form

Now, navigate to the formik-form/src folder and delete all the files except App.js.

Next, create a new file and name it Register.js. This is where you will add your form. Remember to import it in App.js.

Create a React Form

You can create React forms using either controlled components or uncontrolled components. A controlled component is one whose form data is handled by React itself. An uncontrolled component is one whose form data is handled by the DOM.

The official React docs recommend using controlled components. They let you keep track of the form data in local state and therefore have full control of the form.

Below is an example of a form created using a controlled component.

        import { useState } from "react";
const Register = () => {
  const [email, setemail] = useState("");
  const [password, setpassword] = useState("");
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(email);
  };
  const handleEmail = (event) => {
    setemail(event.target.value);
  };
  const handlePassword = (event) => {
    setpassword(event.target.value);
  };
  return (
    <form className="register-form" onSubmit={handleSubmit}>
      <input
        id="email"
        name="email"
        type="email"
        placeholder="Your Email"
        value={email}
        onChange={handleEmail}
      />
      <input
        id="password"
        name="password"
        type="password"
        placeholder="Your password"
        value={password}
        onChange={handlePassword}
      />
      <input type="submit" value="Submit" />
    </form>
  );
};
export default Register;

In the above code, you are initializing the state and creating a handler function for each input field. While this works, your code can easily get repetitive and cluttered especially with many input fields. Adding validation and error message handling is another challenge.

Formik aims to reduce these problems. It makes it easy to handle form state, validate and submit form data.

Add Formik to React

Before using formik, add it to your project using npm.

        npm install formik

To integrate Formik, you will use the useFormik hook. In Register.js, import useFormik at the top of the file:

        import { useFormik } from "formik"

The first step is to initialize the form values. In this case, you will initialize the email and password.

        const formik = useFormik({
    initialValues: {
        email: "",
        password: "",
    },
    onSubmit: values => {
// handle form submission
    },
});

You are also adding the onSubmit function which receives the form values and handles the form submission. For a registration form like this, this could mean creating a new user in the database.

The next step is to use the formik object to get the form values in and out of state.

        <form className="register-form" onSubmit={formik.handleSubmit}>
    <input
    id="email"
    name="email"
    type="email"
    placeholder="Your Email"
    value={formik.values.email}
    onChange={formik.handleChange}
    onBlur={formik.handleBlur}
    />
    <input
    id="password"
    name="password"
    type="password"
    placeholder="Your password"
    value={formik.values.password}
    onChange={formik.handleChange}
    onBlur={formik.handleBlur}
    />
    <input type="submit" value="Submit" />
</form>

In the above code, you are:

  • Giving the input fields an id and name value equal to the one used during initialization in the useFormik hook.
  • Accessing the value of a field, using its name to retrieve it from formik.values.
  • Binding formik.handleChange to the onChange event to display the input values as the user types.
  • Using formik.handleBlur to keep track of visited fields.
  • Binding formik.handleSubmit to the onSubmit event to trigger the onSubmit function you added to the useFormik hook.

Enable Form Validation

When creating a form, it is important to validate user input as it makes user authentication easy since you only store data in the correct format. In your form, for instance, you can check whether the email given is valid and if the password has more than 8 characters.

To validate the form, define a validation function that accepts the form values and returns an error object.

If you add the validation function to useFormik, any validation error found will be available in Formik.errors, indexed on the input name. For example, you can access an error about the email field using Formik.errors.email.

In Register.js, create the validate function and include it in useFormik.

        const formik = useFormik({
    initialValues: {
        email: "",
        password: "",
    },
    validate: () => {
        const errors = {};
        console.log(errors)
        if (!formik.values.email) {
        errors.email = "Required";
        } else if (
        !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i.test(formik.values.email)
        ) {
        errors.email = "Invalid email address";
        }
        if (!formik.values.password) {
        errors.password = "Required";
        } else if (formik.values.password.length < 8) {
        errors.password = "Must be 8 characters or more";
        }
        return errors;
    },
    onSubmit: (values) => {
        console.log("submitted!");
// handle submission
    },
});

Add Error Handling

Next, display the error messages if they exist. Use Formik.touched to check whether the field has been visited. This prevents showing an error for a field the user has not visited yet.

        <form className="register-form">
    <input
    id="email"
    name="email"
    type="email"
    placeholder="Your Email"
    value={formik.values.email}
    onChange={formik.handleChange}
    onBlur={formik.handleBlur}
    />
    {formik.touched.email && formik.errors.email ? <div>{formik.errors.email}</div> : null}
    <input
    id="password"
    name="password"
    type="password"
    placeholder="Your password"
    value={formik.values.password}
    onChange={formik.handleChange}
    onBlur={formik.handleBlur}
    />
    {formik.touched.password && formik.errors.password ? <div>{formik.errors.password}</div> : null}
    <input type="submit" value="Submit" />
</form>

Validate Data Using Yup

Formik provides an easier way to validate forms using the Yup library. Install yup to get started.

        npm install yup

Import yup in Register.js.

        import * as Yup from "yup"

Instead of writing your own custom validation function, use Yup to check if the email and password are valid.

        const formik = useFormik({
    initialValues: {
        email: "",
        password: "",
    },
    validationSchema: Yup.object().shape({
        email: Yup.string()
        .email("Invalid email address")
        .required("Required"),
        password: Yup.string()
        .min(8, "Must be 8 characters or more")
        .required("Required")
    }),
    onSubmit: (values) => {
        console.log("submitted!");
// handle submission
    },
});

And that’s it! You’ve created a simple registration form using Formik and Yup.

Wrapping Everything Up

Forms are an integral part of any application as they allow you to collect user information. In React, creating forms can be a painful experience especially if you are dealing with a lot of data or multiple forms. A tool like Formik provides an easy and seamless way of retrieving and validating form values.