Form validation is a crucial part of any application form, we need to put validation in such a way that the user doesn't fill in the wrong details. We also need to show the appropriate message when a user enters any invalid details.
In the
previous article, we have seen how to manage react forms with
Formik. In this article, we will go further with form validation, we will see how to setup form validation schema, and show the appropriate message.
So let's get started.
Form Validation with Formik
" Formik is designed to manage forms with complex validation with ease. Formik supports synchronous and asynchronous form-level and field-level validation -
Formik Docs".
Formik supports the schema-based form validation with
Yup. Yup is a JavaScript schema builder for value parsing and validation.
We will continue with our previous example at
stackblitz.
Install Yup
Create Validation Schema
We will import the yup and create the validation schema as below,
- const validationSchema = yup.object().shape({
- firstName: yup
- .string()
- .required()
- .min(3),
- lastName: yup.string().required(),
- emailId: yup
- .string()
- .required()
- .email(),
- mobileNumber: yup.number()
- });
Here I have not used any validation message when there is an error, So yup will automatically generate a validation message based on the key.
For example,
- firstName is a required field
- firstName must be at least 3 characters etc.
This is not user friendly, so we will write different message instead of default one as below,
- const validationSchema = yup.object().shape({
- firstName: yup
- .string()
- .required('First name is required.')
- .min(3, 'Minimum 3 characters required'),
- lastName: yup.string().required('Last name is required'),
- emailId: yup
- .string()
- .required('Email ID is required')
- .email('Enter valid email id'),
- mobileNumber: yup.number()
- });
Use Validation Schema
Now we will set this validation schema with useFormik() hook as shown below. Formik uses this validation schema to validate the input controls when the form state is changed.
- const formik = useFormik({
- initialValues: {
- firstName: '',
- lastName: '',
- emailId: '',
- mobileNumber: undefined,
- gender: '',
- address: ''
- },
- onSubmit: values => {
- alert(
- 'Registration Form Submitted \n ' + JSON.stringify(values, null, 2)
- );
- formik.resetForm();
- },
- validationSchema: validationSchema
- });
As you can see in line number 16, we have set the validation schema.
Formik State For Error Handling
Formik object provides various state which we can use to handle the error.
- isValid - true when all validation is fulfilled else false.
- dirty - true when the change in any form control value.
- errors - gives the errors of each form control.
- {
- "firstName": "First name is required.",
- "lastName": "Last name is required",
- "emailId": "Email ID is required"
- }
We will use this property to show the error message for each control.
- touched - touched state of all the form controls.
- {
- "firstName": true,
- "lastName": true,
- "emailId": true
- }
Show Error Message
Now we will use the above states to show error messages for each form control. We will create one function which will take field name as input and render an error message if control is touched and have an error.
- const renderErrorMessage = field => {
- return (
- formik.touched[field] && (
- <div class="text-error">{formik.errors[field]}</div>
- )
- );
- };
We will use this function in each form control as shown below,
- <div>
- <input type="text" {...formik.getFieldProps('firstName')} />
- { renderErrorMessage('firstName') }
- </div>
We have also added CSS in App.css for .text-error.
Final Code
-
-
- import React from 'react';
- import './style.css';
- import { useFormik } from 'formik';
- import * as yup from 'yup';
-
- const validationSchema = yup.object().shape({
- firstName: yup
- .string()
- .required('First name is required.')
- .min(3, 'Minimum 3 characters required'),
- lastName: yup.string().required('Last name is required'),
- emailId: yup
- .string()
- .required('Email ID is required')
- .email('Enter valid email id'),
- mobileNumber: yup.number()
- });
-
- export default function App() {
- const formik = useFormik({
- initialValues: {
- firstName: '',
- lastName: '',
- emailId: '',
- mobileNumber: undefined,
- gender: '',
- address: ''
- },
- onSubmit: values => {
- alert(
- 'Registration Form Submitted \n ' + JSON.stringify(values, null, 2)
- );
- formik.resetForm();
- },
- validationSchema: validationSchema
- });
-
- const renderErrorMessage = field => {
- return (
- formik.touched[field] && (
- <div class="text-error">{formik.errors[field]}</div>
- )
- );
- };
-
- return (
- <div class="root">
- <div class="form">
- <h1> Registration </h1>
- <form onSubmit={formik.handleSubmit}>
- <div class="form-group">
- <label> First Name </label>
- <div>
- <input type="text" {...formik.getFieldProps('firstName')} />
- {renderErrorMessage('firstName')}
- </div>
- </div>
- <div class="form-group">
- <label> Last Name </label>
- <div>
- <input type="text" {...formik.getFieldProps('lastName')} />
- {renderErrorMessage('lastName')}
- </div>
- </div>
- <div class="form-group">
- <label> Email Id </label>
- <div>
- <input type="text" {...formik.getFieldProps('emailId')} />
- {renderErrorMessage('emailId')}
- </div>
- </div>
- <div class="form-group">
- <label> Mobile Number </label>
- <input type="text" {...formik.getFieldProps('mobileNumber')} />
- </div>
- <div class="form-group">
- <label> Gender </label>
- <select {...formik.getFieldProps('gender')}>
- <option value="">Select</option>
- <option value="male">Male</option>
- <option value="female">Female</option>
- </select>
- </div>
- <div class="form-group">
- <label> Address </label>
- <textarea type="text" {...formik.getFieldProps('address')} />
- </div>
- <div>
- <button type="submit" class="btn-primary">
- Submit
- </button>
- <button
- type="reset"
- class="btn-secondary"
- onClick={formik.resetForm}
- >
- Reset
- </button>
- </div>
- </form>
- </div>
- <div class="form-state">
- <h4>Form State</h4>
- <h5>Is Dirty: {JSON.stringify(formik.dirty)}</h5>
- <h5>Valid: {JSON.stringify(formik.isValid)}</h5>
- <h5>values:</h5>
- <code>
- <pre>{JSON.stringify(formik.values, null, 2)}</pre>
- </code>
- <h5>Errors:</h5>
- <code>
- <pre>{JSON.stringify(formik.errors, null, 2)}</pre>
- </code>
- <h5>Touched:</h5>
- <code>
- <pre>{JSON.stringify(formik.touched, null, 2)}</pre>
- </code>
- </div>
- </div>
- );
- }
Final Output
Checkout Live Application
Great !!! We are done with the form validation implementation.
Summary
In this article, we have seen how to do form validation with Formik. We have seen validation schema setup, Formik state values which we have used for showing errors and rendering the error message.
I hope you like this article, give your feedback and suggestion in the comment section below.