DEV Community

Cover image for React Form validations using Formik
Deepak Sharma
Deepak Sharma

Posted on

React Form validations using Formik

Form validations is one of the biggest worries of any frontend developer and no one likes to handle the boilerplate or utils when an elegant solution already exists.

In this article, we'll learn how to use Formik to build a robust form quickly.

We'll be using create-react-app project with following additional dependencies to setup quickly:

yarn add formik yup react-bootstrap bootstrap

There are 3 ways that formik can be used in a project:

  1. useFormik react hook
  2. <Formik /> render props component
  3. withFormik() higher order component

Formik recommends against using the useFormik react hook (ref)

So, we're left with options 2 & 3.

In this post, we'll create a form using <Formik /> render props component.

Link to full source code: https://codesandbox.io/s/github/dpkshrma/formik_react_starter

First, let us setup our form by directly using components from react-bootstrap:

// SignupForm.js

import { Form, Button } from 'react-bootstrap';

const SignupForm = () => {
  return (
    <Form noValidate onSubmit={handleSubmit}>
      <Form.Group>
        <Form.Label>Name</Form.Label>
        <Form.Control
          type="text"
          name="name"
          placeholder="Please enter your name"
        />
      </Form.Group>
      <Form.Group>
        <Form.Label>Email</Form.Label>
        <Form.Control
          type="email"
          name="email"
          placeholder="Please enter your email address"
        />
      </Form.Group>
      <Form.Group>
        <Form.Label>Password</Form.Label>
        <Form.Control
          type="password"
          name="password"
          placeholder="Please enter a strong password"
        />
      </Form.Group>
    </Form>
  )  
}

export default SignupForm;

Now, let us wrap it inside <Formik /> to access all the validation helper functions & state it provides:

import { Formik } from 'formik';

const SignupForm = () => {
  const onSuccess = (values) => {
    alert('All entries are valid' + JSON.stringify(values));
  };
  return (
    <Formik
      onSubmit={onSuccess}
      initialValues={{
        name: '',
        password: '',
        email: ''
      }}
    >
      {({
        handleSubmit,
        handleChange,
        values,
        touched,
        errors,
      }) => {
        return (
          <Form noValidate onSubmit={handleSubmit}>
            <Form.Control
              type="text"
              name="name"
              placeholder="Please enter your name"
              value={values.name}
              onChange={handleChange}
              isInvalid={errors.name}
            />
            <Form.Control.Feedback type="invalid">
              {errors.name}
            </Form.Control.Feedback>
            {/* ... */}
          </Form>
        );
      }}
    </Formik>
  );
}

As you can see, <Formik /> allows us to set initial state of the form using initialValues prop, and handle the submitted values after validation.

Following the render props technique, <Formik /> accepts a function as its child and provides a whole range of helper functions & state variables in function arguments. Some of them are:

  • handleSubmit allows you to automatically handle all the html & custom validations on form submit
  • handleChange can be used with onChange prop of all types of inputs and automatically updates the values correctly after validation (validation on change can be made optional)
  • values object contains the dynamically updated input values. - errors object contains validation errors The key in each key-value pair of values and errors objects come from the name attribute of the input form component.

Now, this is all well and good. We've covered html based validations, but what about custom validation requirements?
<Formik /> has got you covered for this! You can provide custom form validation rules in the validationSchema prop.

We'll use yup to create validation schema. You can use joi as well if you prefer. Below example illustrate how to use the same:

const schema = yup.object({
  name: yup.string().required(),
  password: yup.string()
    .matches(/^(?=.*?[A-Za-z])(?=.*?[0-9]).{8,32}$/, invalidPwdMsg)
    .required(),
  email: yup.string().email('A valid email is required').required(),
});

const SignupForm = () => {
  return (
    <Formik
      validationSchema={schema}
      onSubmit={onSuccess}
    >
      {/* ... */}
    </Formik>
  );
}

yup syntax is very similar to joi. It integrates very well with Formik, and has in built functions to check for email, regex etc. as shown above.

That's all for now! :)
You just learned how to quickly get started and build awesome forms with Formik in React.

Hit the like button if you like this post & follow me if you'd like to read more short tutorials like this.

Top comments (0)