Day 145 - React Forms With Formik

Building forms with React can be painful when you have to do all the things yourself like validation and handeling form submission etc But there is a way to deal with it by using a React library called Formik. Formik helps you create and manage forms in your React project.

Formik helps you with three most important parts of a form in React.

  • Getting values in and out of form state
  • Validation and error messages
  • Handling form submission

Now we know what formik is and what it will do for us we will now see how to use it in our project.

Installing Formik

To install Formik use npm or yarn to add it to your project.

$ npm install formik --save
$ yarn add formik

Formik In React

To create a form with formik in React we use useFormik hook by the Formik Library. useFormik internally uses Formik component which renders a React Contect Provider to manage state of the form and useFormik hook is also not meant for the majority of the use cases. So we will be only using Formik react component to build our forms in React.

First of all import Formik from formik and use it in the return statement. Formik component uses render props pattern to build forms.

import { Formik } from "formik";

const Form = () => {
  return (
    <div>
      <h1>Login</h1>
      <Formik>{}</Formik>
    </div>
  );
};

Formik component requires two props when using the Formik component. One is initialValues and the other is onSubmit

  • initialValues takes a JS object which includes all the initial values of the inputs we use in the form like username and email etc.
  • onSubmit takes a function to deal with the values of the form when we submit the form.

Inside the Formik component it will require a function which will render a form and takes a JS object as an argument. The object arguemnt includes variables like values, handleChange etc to manage the values of the form inputs.

<Formik
  initialValues={{ username: "", password: "" }}
  onSubmit={data => console.log(data)}
>
  {({ values, touched, handleChange, handleBlur, handleSubmit }) => {
    return (
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={values.username}
          onChange={handleChange}
          onBlur={handleBlur}
        />
        <input
          type="password"
          value={values.password}
          onChange={handleChange}
          onBlur={handleBlur}
        />
        <button type="submit">Login</button>
      </form>
    );
  }}
</Formik>

Okay now that we have built a simple form with Formik how can we validate a check for errors?

Form Validation

We can do form validation straight from Formik component. This will do the trick but it is recommended to use a another library called yup to handle form validation. First of all we have to inclue a prop in the Formik component which will check for errors in the form.

<Formik
  initialValues={{ username: "", password: "" }}
  onSubmit={data => console.log(data)}
  validate={data => {
    const errors = {};
    if (!data.username) {
      errors.username = "Username Required!";
    }

    return errors;
  }}
>

After that we can also use errors and isSumbiting values that are passed inside the Formik component render prop. Then we can use these to do validation.

{
  ({
    values,
    touched,
    handleChange,
    handleBlur,
    handleSubmit,
    errors,
    touched,
    isSubmitting,
  }) => {
    // Here comes the form
    {
      // This will print error if there is one
      errors.username && touched.username && errors.username;
    }
  };
}

Simplifying

To simplyfy this more we can use the Form, Field and ErrorMessage components from the Formik library.

import React from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";

const UserForm = () => {
  return (
    <Formik
      initialValues={{ username: "", password: "" }}
      onSubmit={(data, { setSubmitting }) => {
        console.log(JSON.stringify(data, null, 2));
        setSubmitting(false);
      }}
      validate={data => {
        const errors = {};
        if (!data.username) {
          errors.username = "Username Required!";
        }

        return errors;
      }}
    >
      {({ isSubmitting }) => {
        <Form>
          <Field type="text" name="username" />
          <ErrorMessage name="username" component="div" />
          <Field type="password" name="password" />
          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </Form>;
      }}
    </Formik>
  );
};

The values of the form can be accessed by the name we give them in the Field component. Hope you learned something new. Next I will be starting to make my own Design System.


zainscizainsci