Hy coder! Are you building a React application and need to add form validation? Do not worry; we have got you covered. In this article, I'll walk you through the top 4 React form validation libraries: React Hook Form, Formik, Yup, and Final Form. We will break down each library so you can choose the best one for your project.
So let's get started!
The Top 4 Form Validation Libraries
1. React Hook From
Why should we use the React Hook Form?
Weekly downloads via npm: 3m - 4m
npm install react-hook-form
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import "./FormComponent.css";
function App() {
const { register, handleSubmit, formState: { errors: error } } = useForm({});
const [submitted, setSubmitted] = useState(false);
const onSubmit = (data, e) => {
console.log(data);
setSubmitted(true);
e.target.reset();
setTimeout(() => {
setSubmitted(false);
}, 2000);
};
return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<label>First Name</label>
<input {...register("FirstNameRequired", { required: true, maxLength: 10 })} placeholder="First Name" />
{error.FirstNameRequired && <p>First Name is required</p>}
<label>Last Name</label>
<input {...register("LastNameRequired", { required: true, maxLength: 10 })} placeholder="Last Name" />
{error.LastNameRequired && <p>Last Name is required</p>}
{submitted && <div className="success-message">Form has been submitted</div>}
<input type="submit" />
</form>
</>
);
}
export default App;
body {
background: black;
font-family: sans-serif;
}
form {
border: 5px solid #a7a7a7;
border-radius: 5px;
padding: 60px 40px;
max-width: 400px;
margin: 50px auto;
}
input {
box-sizing: border-box;
width: 100%;
border-radius: 3px;
padding: 10px 15px;
}
label {
line-height: 3;
display: block;
margin-bottom: 10px;
margin-top: 20px;
color: white;
}
button[type="submit"],
input[type="submit"] {
background: rgb(158, 87, 25);
color: white;
text-transform: uppercase;
border: none;
cursor: pointer;
margin-top: 40px;
padding: 20px;
letter-spacing: 10px;
}
button[type="submit"],
input[type="submit"]:hover {
background: rgb(135, 74, 21);
}
.success-message {
color: rgb(7, 204, 7);
margin: 10px;
font-size: 15px;
}
p {
color: red;
}
2. Formik
Why should we use Formik?
npm i formik
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import './FormComponent.css';
const App = () => {
const handleSubmit = (data, { resetForm }) => {
alert('Form submitted successfully');
resetForm();
console.log(data);
};
const initialValues = { name: '', email: '', password: '', };
const validate = values => {
const errors = {};
if (!values.name) {
errors.name = 'Name is required';
}
if (!values.email) {
errors.email = 'Email is required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
if (!values.password) {
errors.password = 'Password is required';
} else if (values.password.length < 8) {
errors.password = 'Password must be at least 8 characters';
}
return errors;
};
return (
<div className="form-container">
<h2 className='heading'>Form Validation with Formik</h2>
<Formik
initialValues={initialValues}
validate={validate}
onSubmit={handleSubmit}
>
<Form>
<div className="form-group">
<label htmlFor="name">Name</label>
<Field type="text" name="name" />
<ErrorMessage name="name" component="div" className="error" />
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" className="error" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" className="error" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
</div>
);
};
export default App;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: cursive;
color: white;
}
.form-container {
background-color: rgba(14, 13, 18, 0.933);
height: 100vh;
}
.heading {
text-align: center;
margin-bottom: 20px;
padding-top: 20px;
}
form {
border: 5px solid white;
padding: 50px 30px;
max-width: 400px;
margin: 0 auto;
}
.form-group {
margin-bottom: 20px;
}
input {
border-radius: 5px;
width: 100%;
padding: 8px;
margin: 5px 0 10px 0;
font-size: 16px;
color: black;
}
.error {
color: red;
}
button {
padding: 10px 20px;
margin: 10px 0;
border-radius: 5px;
transition: 0.1s all;
width: 100%;
letter-spacing: 5px;
background-color: rgb(177, 94, 108);
border: none;
cursor: pointer;
}
button:hover {
background-color: rgb(163, 84, 97);
}
3. Yup Library
Why should we use Yup?
npm i yup
import React, { useState } from 'react';
import * as yup from 'yup';
import './FormComponent.css'
const schema = yup.object().shape({
name: yup.string().required('Name is required'),
email: yup.string().email('Invalid email').required('Email is required'),
password: yup.string().min(8, 'Password must be at least 8 characters').required('Password is required'),
});
const App = () => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: ''
});
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
await schema.validate(formData, { abortEarly: false });
console.log('Form data:', formData);
alert('Form has been submitted');
setFormData({ name: '', email: '', password: '' });
setErrors({});
} catch (err) {
const newErrors = {};
err.inner.forEach(error => {
newErrors[error.path] = error.message;
});
setErrors(newErrors);
}
};
return (
<div className='main-container'>
<div className='heading'>
<h2>Form Validation with Yup</h2>
</div>
<form className='form-group' onSubmit={handleSubmit}>
<div>
<label>Name:</label>
<input type="text" name="name" value={formData.name} onChange={handleChange} />
{errors.name && <p>{errors.name}</p>}
</div>
<div>
<label>Email:</label>
<input type="text" name="email" value={formData.email} onChange={handleChange} />
{errors.email && <p>{errors.email}</p>}
</div>
<div>
<label>Password:</label>
<input type="password" name="password" value={formData.password} onChange={handleChange} />
{errors.password && <p>{errors.password}</p>}
</div>
<button type="submit">Submit</button>
</form>
</div>
);
};
export default App;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: cursive;
color: white;
}
.main-container {
background-color: rgba(14, 13, 18, 0.933);
height: 100vh;
}
.heading {
text-align: center;
margin-bottom: 20px;
padding-top: 20px;
}
form {
border: 5px solid rgb(156, 155, 155);
padding: 50px 30px;
max-width: 400px;
margin: 0 auto;
}
.form-group {
margin-bottom: 20px;
}
input {
border-radius: 5px;
width: 100%;
padding: 8px;
margin: 5px 0 10px 0;
font-size: 16px;
color: black;
}
div p {
color: red;
}
button {
padding: 10px 20px;
margin: 10px 0;
border-radius: 5px;
transition: 0.1s all;
width: 100%;
letter-spacing: 5px;
background-color: rgb(177, 94, 108);
border: none;
cursor: pointer;
}
button:hover {
background-color: rgb(163, 84, 97);
}
4. React Final Form
Why should we use React Final Form?
npm i react-final-form
import React from 'react';
import { Form, Field } from 'react-final-form';
import './FormComponent.css'; // Import your CSS file for styling
const initialValues = {
name: '',
email: '',
password: '',
};
const App = () => {
const handleSubmit = (values, form) => {
alert('Form submitted successfully');
form.restart(); // Reset both values and touched states
};
const validate = values => {
const errors = {};
if (!values.name) {
errors.name = 'Name cannot be empty';
}
if (!values.email) {
errors.email = 'Email is required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
if (!values.password) {
errors.password = 'Password is required';
} else if (values.password.length < 6) {
errors.password = 'Password must be at least 6 characters';
}
return errors;
};
return (
<div className="form-container">
<h2 className='heading'>Form Validation with Final Form</h2>
<Form
initialValues={initialValues}
onSubmit={handleSubmit}
validate={validate}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="name">Name</label>
<Field name="name">
{({ input, meta }) => (
<div className='error'>
<input {...input} type="text" className={meta.error && meta.touched ? 'error' : ''} />
{meta.error && meta.touched && meta.error}
</div>
)}
</Field>
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field name="email">
{({ input, meta }) => (
<div className='error'>
<input {...input} type="email" className={meta.error && meta.touched ? 'error' : ''} />
{meta.error && meta.touched && meta.error}
</div>
)}
</Field>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field name="password">
{({ input, meta }) => (
<div className='error'>
<input {...input} type="password" className={meta.error && meta.touched ? 'error' : ''} />
{meta.error && meta.touched && meta.error}
</div>
)}
</Field>
</div>
<button type="submit">Submit</button>
</form>
)}
/>
</div>
);
};
export default App;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: cursive;
color: white;
}
.form-container {
background-color: rgba(14, 13, 18, 0.933);
height: 100vh;
}
.heading {
text-align: center;
margin-bottom: 20px;
padding-top: 20px;
}
form {
max-width: 400px;
margin: 0 auto;
}
.form-group {
margin-bottom: 20px;
}
input {
border-radius: 5px;
width: 100%;
padding: 8px;
margin: 5px 0 10px 0;
font-size: 16px;
color: black;
}
.error {
color: red;
}
button {
padding: 10px 20px;
margin: 10px 0;
border-radius: 5px;
transition: 0.1s all;
width: 100%;
letter-spacing: 5px;
background-color: rgb(177, 94, 108);
border: none;
cursor: pointer;
}
button:hover {
background-color: rgb(163, 84, 97);
}
Which one should I choose?
Lots of People Use It: Many React developers like using the React Hook Form. If you need help, there are plenty of others who know how to use it.
Gets Regular Updates: It's always getting better. The people who make React Hook Form are always fixing bugs and adding new stuff.
Flexible: You can customize it to fit your needs. So, you're not stuck with a one-size-fits-all solution.
Lots of Help Available: The React Hook Form comes with lots of guides and examples. If you get stuck, you can find help easily.