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
- Easy Form State Management
Formik manages form state using React’s state management functionality, which allows developers to manage complicated forms with ease. - Validation
Formik allows developers to perform inline field level validation and provide feedback in a concise manner. - 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. - 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. - Localization
Formik provides a feature to switch between the types, labels, and snippets of text to handle internationalization without difficulty. - Multiple Input Components
Formik supports different types of input components, such as radio buttons, checkboxes, select boxes, text input, and textarea components.
Advantages
- 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. - 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. - 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:
- Node.js & Npm or Yarn
- 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
- 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
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 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)
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
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 […]
How To Use Environment Variables In React
Introduction Have you ever had to work on a React application and found yourself dealing with different environments or sensitive data? Setting up environment variables can make your life easier and provide a safer way to store information that should not be accessible to the public. In this article, we’re going to look at how […]
Create Forms In React Using React Hook Form
Introduction React Hook Form is a popular tool used in building forms in React.js. It is a performant library that simplifies the process of building forms by reducing boilerplate code and providing convenient features. This article is aimed at introducing the basic concepts of React Hook Form and how to use it to create forms […]