Categories
React

Make Form Handling Easy in React Apps with Formik — Hooks

Spread the love

Formik is a library that makes form handling in React apps easy.

In this article, we’ll look at how to handle form inputs with Formik

useField

We can use the useField hook to create our own text fields that work with Formik.

For instance, we can write:

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

const MyTextField = ({ label, ...props }) => {
  const [field, meta] = useField(props);
  return (
    <>
      <label>
        {label}
        <input {...field} {...props} />
      </label>
      {meta.touched && meta.error ? (
        <div className="error">{meta.error}</div>
      ) : null}
    </>
  );
};

export const FormExample = () => (
  <div>
    <Formik
      initialValues={{
        email: ""
      }}
      onSubmit={(values, actions) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          actions.setSubmitting(false);
        }, 1000);
      }}
    >
      {(props) => (
        <Form>
          <MyTextField name="email" type="email" label="Email" />
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);
export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

We create the MyTextField component with the useField hook.

And we pass in the props and the field objects into the input as props to let Formik bind to states and set input statuses like touched and error .

Then in FormExample , we create our form with the Formik and Form components as usual.

But we use the MyTextField component to add our input field into the form.

useFormik

We can use the useFormik hook to create Formik forms.

For instance, we can write:

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

export const FormExample = () => {
  const formik = useFormik({
    initialValues: {
      firstName: "",
      lastName: "",
      email: ""
    },
    onSubmit: (values) => {
      alert(JSON.stringify(values, null, 2));
    }
  });
  return (
    <form onSubmit={formik.handleSubmit}>
      <label htmlFor="firstName">First Name</label>
      <input
        id="firstName"
        name="firstName"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.firstName}
      />
      <label htmlFor="lastName">Last Name</label>
      <input
        id="lastName"
        name="lastName"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.lastName}
      />
      <label htmlFor="email">Email Address</label>
      <input
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        value={formik.values.email}
      />
      <button type="submit">Submit</button>
    </form>
  );
};

export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

We add the useFormik to FormExample to let us create a form with Formik.

We pass the initialValues inside to set the initial values.

onSubmit has the submit handler for the form.

Then we can get the properties from the formik object.

This includes the onSubmit callback, which is set to formik.handleSubmit .

formik.handleChange is the change handler for the form fields.

form.values has the form values.

useFormikContext

We can use the useFormikContext hook to let us access the form from components inside the form.

For instance, we can write:

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

const AutoSubmitToken = () => {
  const { values, submitForm } = useFormikContext();
  React.useEffect(() => {
    if (values.token.length === 6) {
      submitForm();
    }
  }, [values, submitForm]);
  return null;
};

export const FormExample = () => {
  return (
    <Formik
      initialValues={{ token: "" }}
      validate={(values) => {
        const errors = {};
        if (values.token.length < 5) {
          errors.token = "Invalid code. Too short.";
        }
        return errors;
      }}
      onSubmit={(values, actions) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          actions.setSubmitting(false);
        }, 1000);
      }}
    >
      <Form>
        <Field name="token" type="tel" />
        <AutoSubmitToken />
      </Form>
    </Formik>
  );
};

export default function App() {
  return (
    <div className="App">
      <FormExample />
    </div>
  );
}

We have the AutoSubmitToken component that has the values property with the form values.

submitForm has the form submit function.

useFormikContext returns an object with all those properties.

The FormExample has the usual props and components to create the form and the AutoSubmitToken component that submits the form automatically values.token.length is bigger than or equal to 6.

Conclusion

We can use the hooks that comes with Formik to create our forms.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *