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 […]
How To Use Google Login With React
As a developer, I cannot stress enough the importance of creating a seamless user experience when it comes to authentication. One of the most popular and convenient ways to allow users to authenticate is by using Google Login. In this article, we’ll explore how to use Google Login with React. Before we delve deep into […]
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 […]
What Is JSX and how to use it.
Introduction As a web developer, I’m always on the lookout for new tools and technologies that can help me write better code faster. One tool that has caught my attention lately is Typescript JSX. In this article, I’m going to share my experience learning Typescript JSX and the benefits it has brought to my development […]
React JS vs Svelte
Introduction In the world of web development, there are many frameworks available for use. Two of the most popular frameworks are React JS and Svelte. React JS is an open-source JavaScript library developed by Facebook while Svelte is a relatively new framework developed by Rich Harris in 2016. In this article, we will compare React […]
Mastering Hooks In React JS
Introduction React JS is a popular JavaScript library that has gained a lot of popularity since its introduction in 2013. It has been adopted by many web developers who use it to build robust and reliable web applications. With React JS, developers can create user interfaces by building reusable UI components, which can be combined […]