Create Forms In React JS Using Formik

Introduction

React JS is a widely used system for building complex and dynamic web applications. It allows developers to work with reusable components in a more efficient way than traditional JavaScript frameworks. One crucial aspect of developing web applications is building forms, which are used to collect user input and send it to a server. In this article, we will explore an essential tool for building forms with React JS, known as Formik.

Using Formik, developers can effortlessly manage the state of complex forms with minimal coding. In this article, we’ll walk through how to create a form using Formik and explore some of its key features and advantages.

Background on Formik

Formik is a library that helps manage forms in React JS. It provides an easy way of handling form data while reducing boilerplate code and delivering a better user experience. Formik also provides options for validation, masking data inputs, and handling asynchronous form submission.

Features

  1. Easy Form State Management
    Formik manages form state using React’s state management functionality, which allows developers to manage complicated forms with ease.
  2. Validation
    Formik allows developers to perform inline field level validation and provide feedback in a concise manner.
  3. Faster Development
    Developers can use Formik as a better alternative of wiring up forms, which saves time, reduces boilerplate code, and allows developers to focus on the business logic.
  4. Handles Form Submission
    Formik enables client-side form submission, and it is easy to use, supports post-processing, and allows developers to build customized submission workflows.
  5. Localization
    Formik provides a feature to switch between the types, labels, and snippets of text to handle internationalization without difficulty.
  6. Multiple Input Components
    Formik supports different types of input components, such as radio buttons, checkboxes, select boxes, text input, and textarea components.

Advantages

  1. Helps reduce Form Fatigue
    Formik helps minimize the number of redundant form validation code required at the client-side and server-side, resulting in at reducing form fatigue.
  2. Enables better User Experience
    Formik provides the ability to customize the user interface experience by engaging with users in real-time and providing instant feedback. It can make the form interactive and more user-friendly.
  3. Provides Developer Flexibility
    Formik allows developers to customize the client-side logic concerning form submission, sync-ups with the server-side, and data validation at the client-side.

Getting Started with Formik

Before starting with Formik, you must have an understanding of React state management and Lifecycle methods in React. If you’re already familiar with React JS, getting started with Formik is straightforward.

Requirements

To start using Formik, you’ll need to install the library using npm or yarn. You’ll also need to have the following:

  1. Node.js & Npm or Yarn
  2. React.js

Installing Formik

To install Formik on your computer using npm, type the following command:

 npm install formik 

And if you’re using yarn, type:

yarn add formik

Next, you’ll need to import it in your file:

import { Formik } from "formik";

Importing Formik

To speed up the process, we’ll use a Formik component, which takes two props: initialValues and onSubmit.

For example, we could write:

<Formik
  initialValues={{ name: "", email: "" }}
  onSubmit={(values, { setSubmitting }) => {
    alert(JSON.stringify(values));
  }}
>
{(props) => (
  <form onSubmit={props.handleSubmit}>
    <input
      type="text"
      name="name"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.name}
    />
    <input
      type="email"
      name="email"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.email}
    />
    <button type="submit" disabled={props.isSubmitting}>
      Submit
    </button>
  </form>
)}
</Formik>

Creating a Simple Form With Formik

Now that we’ve got Formik installed and imported in our file, let’s create a simple form. To do so, we will use an input element and attach it to Formik using the handleChange, handleSubmit, and values properties.

For example, let’s create a simple contact information form with the following fields:

  • First Name
  • Last Name
  • Email
  • Phone Number

Here’s the code for the form:

<Formik
  initialValues={{ firstName: "", lastName: "", email: "", phoneNumber: "" }}
  onSubmit={(values) => {
    console.log(values);
  }}
>
{(props) => (
  <form onSubmit={props.handleSubmit}>
    <label htmlFor="firstName">First Name</label>
    <input
      type="text"
      id="firstName"
      name="firstName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.firstName}
      placeholder="Enter your first name"
    />
    <label htmlFor="lastName">Last Name</label>
    <input
      type="text"
      id="lastName"
      name="lastName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.lastName}
      placeholder="Enter your last name"
    />
    <label htmlFor="email">Email</label>
    <input
      type="email"
      id="email"
      name="email"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.email}
      placeholder="Enter your email address"
    />
    <label htmlFor="phoneNumber">Phone Number</label>
    <input
      type="text"
      id="phoneNumber"
      name="phoneNumber"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.phoneNumber}
      placeholder="Enter your phone number"
    />
    <button type="submit">Submit</button>
  </form>
)}
</Formik>

Here we’ve defined our initialValues, which consists of an object that contains empty values for firstName, lastName, email, and phoneNumber. When the form is submitted, the onSubmit function will be triggered, which will log the form values to the console.

When we include the Formik component, we pass a function that returns the JSX elements that represent our form. Inside the form, we use labels to provide a descriptive name for each field and inputs to receive user input.

Implementing Form Validation using Yup

Validation is an essential feature of any form as it ensures that users submit correct data that is valid according to the defined rules. Formik provides seamless integration with Yup, which is a JavaScript schema validation library. Here’s how to implement validation:

// Importing Yup

import * as Yup from 'yup';

<Formik

  initialValues={{ firstName: "", lastName: "", email: "", phoneNumber: "" }}

  onSubmit={(values) => {

    console.log(values);

  }}

  validationSchema={Yup.object().shape({

    firstName: Yup.string()

      .min(2, 'Too Short!')

      .max(50, 'Too Long!')

      .required('Required'),

    lastName: Yup.string()

      .min(2, 'Too Short!')

      .max(50, 'Too Long!')

      .required('Required'),

    email: Yup.string()

      .email('Invalid email')

      .required('Required'),

    phoneNumber: Yup.string()

      .matches(/^[0-9]*$/, 'Must use numbers only')

      .min(10, "Phone numbers can't be shorter than 10 digits")

      .max(10, "Phone numbers can't be longer than 10 digits")

      .required('Required'),

  })}

>

{(props) => (

  <form onSubmit={props.handleSubmit}>

    <label htmlFor="firstName">First Name</label>

    <input

      type="text"

      id="firstName"

      name="firstName"

      onChange={props.handleChange}

      onBlur={props.handleBlur}

      value={props.values.firstName}

      placeholder="Enter your first name"

      className={props.errors.firstName && props.touched.firstName ? "error" : null}

    />

    {props.errors.firstName && props.touched.firstName ? (

      <div className="error-message">{props.errors.firstName}</div>

    ) : null}

    <label htmlFor="lastName">Last Name</label>

    <input

      type="text"

      id="lastName"

      name="lastName"

      onChange={props.handleChange}

      onBlur={props.handleBlur}

      value={props.values.lastName}

      placeholder="Enter your last name"

      className={props.errors.lastName && props.touched.lastName ? "error" : null}

    />

    {props.errors.lastName && props.touched.lastName ? (

      <div className="error-message">{props.errors.lastName}</div>

    ) : null}

    <label htmlFor="email">Email</label>

    <input

      type="email"

      id="email"

      name="email"

      onChange={props.handleChange}

      onBlur={props.handleBlur}

      value={props.values.email}

      placeholder="Enter your email address"

      className={props.errors.email && props.touched.email ? "error" : null}

    />

    {props.errors.email && props.touched.email ? (

      <div className="error-message">{props.errors.email}</div>

    ) : null}

    <label htmlFor="phoneNumber">Phone Number</label>

    <input

      type="text"

      id="phoneNumber"

      name="phoneNumber"

      onChange={props.handleChange}

      onBlur={props.handleBlur}

      value={props.values.phoneNumber}

      placeholder="Enter your phone number"

      className={props.errors.phoneNumber && props.touched.phoneNumber ? "error" : null}

    />

    {props.errors.phoneNumber && props.touched.phoneNumber ? (

      <div className="error-message">{props.errors.phoneNumber}</div>

    ) : null}

    <button type="submit">Submit</button>

  </form>

)}

</Formik>

“`

“`

Here we’ve imported the Yup library and used the validationSchema property on the Formik component to define our validation rules. We’ve defined four fields (firstName, lastName, email, phoneNumber) and defined the rules for each. For instance, we’ve used the min method to ensure that firstName is at least two characters, the max method to ensure that firstName is no more than fifty characters, and required to ensure that users enter information.

In addition, we’ve used className to apply a error class to the inputs if there are any validation errors, and props.errors and props.touched to display error messages if input is invalid.

Displaying Form Errors Using Formik

When the user submits an invalid form, we want to provide feedback to them in a clear and concise manner. Formik includes functionality for displaying errors safely and intuitively with minimal coding.

<Formik
  initialValues={{ firstName: "", lastName: "", email: "", phoneNumber: "" }}
  onSubmit={(values) => {
    console.log(values);
  }}
  validationSchema={Yup.object().shape({
    firstName: Yup.string()
      .min(2, 'Too Short!')
      .max(50, 'Too Long!')
      .required('Required'),
    lastName: Yup.string()
      .min(2, 'Too Short!')
      .max(50, 'Too Long!')
      .required('Required'),
    email: Yup.string()
      .email('Invalid email')
      .required('Required'),
    phoneNumber: Yup.string()
      .matches(/^[0-9]*$/, 'Must use numbers only')
      .min(10, "Phone numbers can't be shorter than 10 digits")
      .max(10, "Phone numbers can't be longer than 10 digits")
      .required('Required'),
  })}
>
{(props) => (
  <form onSubmit={props.handleSubmit}>
    <label htmlFor="firstName">First Name</label>
    <input
      type="text"
      id="firstName"
      name="firstName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.firstName}
      placeholder="Enter your first name"
      className={props.errors.firstName && props.touched.firstName ? "error" : null}
    />
    {props.errors.firstName && props.touched.firstName ? (
      <div className="error-message">{props.errors.firstName}</div>
    ) : null}

    <label htmlFor="lastName">Last Name</label>
    <input
      type="text"
      id="lastName"
      name="lastName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.lastName}
      placeholder="Enter your last name"
      className={props.errors.lastName && props.touched.lastName ? "error" : null}
    />
    {props.errors.lastName && props.touched.lastName ? (
      <div className="error-message">{props.errors.lastName}</div>
    ) : null}

    <label htmlFor="email">Email</label>
    <input
      type="email"
      id="email"
      name="email"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.email}
      placeholder="Enter your email address"
      className={props.errors.email && props.touched.email ? "error" : null}
    />
    {props.errors.email && props.touched.email ? (
      <div className="error-message">{props.errors.email}</div>
    ) : null}

    <label htmlFor="phoneNumber">Phone Number</label>
    <input
      type="text"
      id="phoneNumber"
      name="phoneNumber"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.phoneNumber}
      placeholder="Enter your phone number"
      className={props.errors.phoneNumber && props.touched.phoneNumber ? "error" : null}
    />
    {props.errors.phoneNumber && props.touched.phoneNumber ? (
      <div className="error-message">{props.errors.phoneNumber}</div>
    ) : null}

    <button type="submit">Submit</button
</form>
)}
</Formik>

In this code snippet, we’ve used the props.errors and props.touched properties to render an error message when input is invalid. Note that we’ve wrapped the error message component in an if statement to make sure that error messages are only displayed when the input field is touched and invalid.

Submitting the Form

So far, we’ve created a form that validates user input and displays error messages. Now, we need to submit the form to the server. In React, we typically handle form submission through an event listener attached to the form element. In Formik, we handle submission through the onSubmit property on the Formik component.

<Formik
  initialValues={{ firstName: "", lastName: "", email: "", phoneNumber: "" }}
  onSubmit={(values) => {
    console.log(values);
  }}
  validationSchema={Yup.object().shape({
    firstName: Yup.string()
      .min(2, 'Too Short!')
      .max(50, 'Too Long!')
      .required('Required'),
    lastName: Yup.string()
      .min(2, 'Too Short!')
      .max(50, 'Too Long!')
      .required('Required'),
    email: Yup.string()
      .email('Invalid email')
      .required('Required'),
    phoneNumber: Yup.string()
      .matches(/^[0-9]*$/, 'Must use numbers only')
      .min(10, "Phone numbers can't be shorter than 10 digits")
      .max(10, "Phone numbers can't be longer than 10 digits")
      .required('Required'),
  })}
>
{(props) => (
  <form onSubmit={props.handleSubmit}>
    <label htmlFor="firstName">First Name</label>
    <input
      type="text"
      id="firstName"
      name="firstName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.firstName}
      placeholder="Enter your first name"
      className={props.errors.firstName && props.touched.firstName ? "error" : null}
    />
    {props.errors.firstName && props.touched.firstName ? (
      <div className="error-message">{props.errors.firstName}</div>
    ) : null}

    <label htmlFor="lastName">Last Name</label>
    <input
      type="text"
      id="lastName"
      name="lastName"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.lastName}
      placeholder="Enter your last name"
      className={props.errors.lastName && props.touched.lastName ? "error" : null}
    />
    {props.errors.lastName && props.touched.lastName ? (
      <div className="error-message">{props.errors.lastName}</div>
    ) : null}

    <label htmlFor="email">Email</label>
    <input
      type="email"
      id="email"
      name="email"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.email}
      placeholder="Enter your email address"
      className={props.errors.email && props.touched.email ? "error" : null}
    />
    {props.errors.email && props.touched.email ? (
      <div className="error-message">{props.errors.email}</div>
    ) : null}

    <label htmlFor="phoneNumber">Phone Number</label>
    <input
      type="text"
      id="phoneNumber"
      name="phoneNumber"
      onChange={props.handleChange}
      onBlur={props.handleBlur}
      value={props.values.phoneNumber}
      placeholder="Enter your phone number"
      className={props.errors.phoneNumber && props.touched.phoneNumber ? "error" : null}
    />
    {props.errors.phoneNumber && props.touched.phoneNumber ? (
      <div className="error-message">{props.errors.phoneNumber}</div>
    ) : null}

    <button type="submit">Submit</button>
  </form>
)}
</Formik>

In this code snippet, we’ve defined an onSubmit property on the Formik component that logs the form values to the console when the form is submitted. We’ve also added a submit button to the form.

Conclusion

In this tutorial, we’ve covered a lot of ground. We’ve introduced Formik, a popular form management library for React, and we’ve demonstrated how to use it to validate user input and handle form submission. We’ve also covered the basics of form validation and error handling, and we’ve provided code examples that you can use as templates for your own projects.

Formik is a powerful tool that can make form management in React much more efficient and less error-prone. By using Formik to manage form state, you can reduce the amount of boilerplate code you need to write, and you can keep your components focused on rendering UI elements.

With Formik, you can build complex forms with ease, and you can provide your users with a seamless, error-free form experience. Try implementing Formik in your own projects, and see how it can help you build forms faster, better, and more reliably.

Routing In React JS Using React Router
React JS | Uncategorized

Routing In React JS Using React Router

Introduction React JS has become one of the most popular frontend frameworks for web development. It allows developers to create complex and dynamic user interfaces with ease. Routing is an essential part of web development, and React Router is one such library that is used to manage routing in React applications. In this article, we’ll […]

Lifecycle Hooks in React JS – Introduction
React JS | Uncategorized

Lifecycle Hooks in React JS – Introduction

React JS is one of the most popular front-end frameworks used by developers worldwide. It offers great flexibility and reusability because of its component-based architecture. A component in React is an independent and reusable piece of UI, and it can be thought of as a function of state and props. React provides lifecycle hooks that […]

React JS Interview Questions (and answers)
React JS

React JS Interview Questions (and answers)

Introduction: React is a powerful JavaScript library with a growing presence in web development today. With its powerful rendering capabilities and cross-functional library, it has become an important skill for developers to learn. In order to prepare for React interviews, it is important to familiarize yourself with React interview questions, which cover a range of […]

React JS vs Angular: A Comprehensive Guide
React JS

React JS vs Angular: A Comprehensive Guide

Introduction Web development has come a long way since the earlier days of static HTML pages. Web applications have become more dynamic, interactive and more like native applications. This transformation has brought about the rise of JavaScript frameworks and libraries, which have become essential in building web applications. However, choosing between these libraries or frameworks […]