Build Robust and User-Friendly Forms by using Formik and Validate using Yup in ReactJS
Q1. what are the popular 3rd Party for Forms in React?
- Formik [ Popular ]
- KendoForms
- React-Hook-Forms [Trending after React 16+ version]
- React-Final-Forms etc.
In this blog, we will setup formik and yup library for form and validating the form.
Let’s get stated with Formik:
Note: In this blog, I have used bootstrap for styling
Step 1. Install Formik library for your project.
$ npm install formik --save
Step 2. Import useFormik hook
import {useFormik} from 'formik';
Step 3. Configure formik form with values and submit event.
const formik = useFormik({
initialValues: {},
onSubmit: function(){},
})
- initialValues is an Object that defines the values to use for form.
- onSubmit defines the actions to perform on form submit.
Step 4. Binding the formik values and events to form elements
<form onSubmit={formik.handleSubmit}>
<input
type='text
name='username'
value={formik.values.UserName}
onChange={formik.handleChange}
/>
</form>
Step 5. Accessing the form data and using into component:
<dd>{formik.values.UserName} </dd>
const formik = useFormik({
initialValues: {}.
onSubmit: function(values){
alert(JSON.stringify(values);
},
})
Example:
Example 1. Simple Code
import { Formik, useFormik } from "formik";
import React from "react";
const FormikDemo = () => {
const formik = useFormik({
initialValues: {
username: "",
password: "",
city: "",
},
onSubmit: (values) => {
alert(JSON.stringify(values));
},
});
return (
<div className="container fluid">
<form onSubmit={formik.handleSubmit}>
<h2>Register User</h2>
<dl>
<dt>User Name:</dt>
<dd>
<input
type="text"
name="username"
value={formik.values.username}
onChange={formik.handleChange}
required
/>
</dd>
<dt>Password: </dt>
<dd>
<input
type="password"
name="password"
value={formik.values.password}
onChange={formik.handleChange}
required
/>
</dd>
<dt>Select the City:</dt>
<dd>
<select
name="city"
value={formik.values.city}
onChange={formik.handleChange}
required
>
<option value="">---Select City---</option>
<option value="bangalore">Bangalore</option>
<option value="delhi">Delhi</option>
<option value="mumbai">Mumbai</option>
<option value="chennai">Chennai</option>
</select>
</dd>
</dl>
<button className="btn btn-primary" >Submit</button>
</form>
{/* <dd>{JSON.stringify(formik.values)}</dd> */}
</div>
);
};
export default FormikDemo;
Example 2. With boolean values:
import { Formik, useFormik } from "formik";
import React from "react";
const FormikDemo = () => {
const formik = useFormik({
initialValues: {
username: "",
password: "",
city: "",
subscribed: false,
},
onSubmit: (values) => {
alert(`Name: ${values.username}\n Subscribed: ${values.subscribed ? " subscribed" : "Not subscribed"}`);
},
});
return (
<div className="container fluid">
<form onSubmit={formik.handleSubmit}>
<h2>Register User</h2>
<dl>
<dt>User Name:</dt>
<dd>
<input
type="text"
name="username"
value={formik.values.username}
onChange={formik.handleChange}
required
/>
</dd>
<dt>Password: </dt>
<dd>
<input
type="password"
name="password"
value={formik.values.password}
onChange={formik.handleChange}
required
/>
</dd>
<dt>Select the City:</dt>
<dd>
<select
name="city"
value={formik.values.city}
onChange={formik.handleChange}
required
>
<option value="">---Select City---</option>
<option value="bangalore">Bangalore</option>
<option value="delhi">Delhi</option>
<option value="mumbai">Mumbai</option>
<option value="chennai">Chennai</option>
</select>
</dd>
<dt>Subscribe</dt>
<dd className="form-check form-switch">
<input className="form-check-input" type="checkbox" name="subscribed" checked={formik.values.subscribed} onChange={formik.handleChange} />
</dd>
</dl>
<button className="btn btn-primary">Submit</button>
</form>
{/* <dd>{JSON.stringify(formik.values)}</dd> */}
</div>
);
};
export default FormikDemo;
How to handle the validations using Formik:
- Validation is the process of verifying user input.
- Validation is required to ensure that contradictionary and unauthorized data is not get stored into the database.
- React can handle validations without help of third party by using javascript functions. [ It is lenghty process. ]
isNaN(): to verify number or not.
indexOf()
typeOf etc.
We have to use javascript things to validations.
- React have to use various events to verify the value
onBlur
onKeyUp
onFocus
onChange etc.
- You configure validation for every element in page by using validation function.
- Formik can use Validation, form validation function that returns errors object.
- Here too, you have to javascript methods for verifying the value.
Step 1. Create a function for accepting form values, verfying the values and reporting errors.
function validateForm(values){
const errors = {};
if(values.Name == '') {errors.Name = 'required'}
if(values.Email == '') {errors.Email='required'}
}
useFormik({
initialValues: {},
validation: ValidateForm
})
- You can access error message by using
{formik.errors.Name}
Example 1: Single condition Validation
import React from "react";
import { useFormik } from "formik";
const FormikValidation = () => {
const formik = useFormik({
initialValues: {
username: "",
age: "",
email: "",
},
onSubmit: (values) => {
alert(`Name: ${values.username}\n age: ${values.age}`);
},
validate: (values) => {
let errors = {};
if (!values.username) {
errors.username = "Required";
}
if (!values.age) {
errors.age = "Required";
}
if (!values.email) {
errors.email = "Required";
}
return errors;
}
});
return (
<div className="container-fluid">
<h2>Register</h2>
<form onSubmit={formik.handleSubmit}>
<dl>
<dt>User Name:</dt>
<dd>
<input
type="text"
name="username"
placeholder="User Name"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.username}</dd>
<dt>Age:</dt>
<dd>
<input
type="text"
name="age"
placeholder="age"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.age}</dd>
<dt>Email:</dt>
<dd>
<input
type="email"
name="email"
placeholder="email"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.email}</dd>
</dl>
<button className="btn btn-primary" >Register</button>
</form>
</div>
);
};
export default FormikValidation;
Example 2: Multiple validations
import React from "react";
import { useFormik } from "formik";
const FormikValidation = () => {
const formik = useFormik({
initialValues: {
username: "",
age: "",
email: "",
mobile: "",
},
validate: (values) => {
let errors = {};
// Validation for username
if (!values.username) {
errors.username = "Required";
} else if (values.username.length > 10) {
errors.username = "Must be less than 10 characters";
} else if (values.username.length < 4) {
errors.username = "Must be more than 4 characters";
}
// Validation for age
if (!values.age) {
errors.age = "Required";
} else if (isNaN(values.age)) {
errors.age = "Must be a number";
}
// Validation for email (Improved)
if (!values.email) {
errors.email = "Required";
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) {
errors.email = "Invalid email format";
}
// Validation for mobile number
if (!values.mobile) {
errors.mobile = "Required";
} else if (!values.mobile.match(/\+91\d{10}/)) {
errors.mobile =
"Invalid mobile number (Must start with +91 and be 10 digits)";
} // No need to set errors.mobile to "" here
return errors;
},
onSubmit: (values) => {
alert(`Name: ${values.username}\n age: ${values.age}`);
},
});
return (
<div className="container-fluid">
<h2>Register</h2>
<form onSubmit={formik.handleSubmit}>
<dl>
<dt>User Name:</dt>
<dd>
<input
type="text"
name="username"
placeholder="User Name"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.username}</dd>
<dt>Age:</dt>
<dd>
<input
type="text"
name="age"
placeholder="age"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.age}</dd>
<dt>Email:</dt>
<dd>
<input
type="email"
name="email"
placeholder="email"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.email}</dd>
<dt>Mobile :</dt>
<dd>
<input
type="text"
name="mobile"
placeholder="mobile number"
onChange={formik.handleChange}
/>
</dd>
<dd className="text-danger">{formik.errors.mobile}</dd>
</dl>
<button className="btn btn-primary">Register</button>
</form>
</div>
);
};
export default FormikValidation;
Let’s Validate using Yup Library:
Validation Using YUP Library:
- It simplifies the form and its validation.
- Yup library provides validation schemas.
- Every validation schema[Structure] defines the type and range of value.
- Validation Schema is Data Structure.
- Like previously, you need not to explicitly any function to verify the data type or range using javaScript functions.
Yup library provides schemas for validations, for example:
- BooleanSchema
- NumberSchema
- StringSchema
there are many like this…
Yup provides functions for verifying range and pattern.
- min()
- max()
- maxLength()
- minlength()
- required()
- pattern()
- email() etc.
Step 1. Install Yup library for Project:
$ npm install yup --save
Step 2. Import Validation schemas in Component:
import * as yup from 'yup';
Step 3. Formik can use Yup validation schema by using “validationSchema” property.
const formik = useFormik({
initialValues: {},
validationSchema: yup.object({
FieldName: yup.DataType().required().min(4).max(10),
})
})
Step 4. Binding the fields with HTML elements.
<input type="text" {...formik.getFieldProps("Name")}/>
We need to configure errors, Internally It will managed yup library.
<dd>{formik.errors.name}</dd>
Example:
Yup validation:
import { useFormik } from "formik";
import React from "react";
import * as yup from "yup";
const YupValidation = () => {
const formik = useFormik({
initialValues: {
username:'',
password: '',
email:'',
},
validationSchema: yup.object({
username: yup.string()
.required('Username is required')
.min(5, 'Username must be at least 5 characters long')
.max(15, 'username must be at max 15 characters long'),
password: yup.string()
.required('Password is required')
.min(8, 'Password must be at least 8 characters long'),
email: yup.string()
.required('Email is required')
.email('Invalid Email!'),
}),
onSubmit: (values) => {
alert(JSON.stringify(values));
},
});
return (
<div className="container-fluid w-25">
<h2>Register</h2>
<form onSubmit={formik.handleSubmit}>
<div className="form-group">
<label htmlFor="name">User Name:</label>
<input type="text" className="form-control" id="name" {...formik.getFieldProps('username')}/>
</div>
<p className="text-danger">{formik.errors.username}</p>
<div className="form-group">
<label htmlFor="email">Email</label>
<input type="email" className="form-control" id="email" {...formik.getFieldProps('email')}/>
</div>
<p className="text-danger">{formik.errors.email}</p>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" className="form-control" id="password" {...formik.getFieldProps('password')}/>
</div>
<p className="text-danger">{formik.errors.password}</p>
<br />
<button type="submit" className="btn btn-primary">
Register
</button>
</form>
</div>
);
};
export default YupValidation;
Output:
…