Proper email validation is a fundamental part of any React application that collects user data. You'll find five distinct methods for implementation, each with code snippets. We'll also look at the shortcomings of these traditional approaches and how Abstract API provides a more robust solution.
How to Implement Email Validation in React
Here are four common methods to validate email addresses in a React application. Each approach has a distinct implementation, from browser-native features to external libraries.
Browser Constraint-Validation
This method leverages built-in HTML5 features. When you render an input with "type='email'", React passes this attribute directly to the DOM, which provides browser-supplied pattern validation for free. The code uses a "useRef" hook to get a direct reference to the input element.
The "handleSubmit" function calls "reportValidity()" on the input. This function triggers the browser's built-in validation UI and returns true if the input is valid. This approach works even before the React application fully loads, an example of progressive enhancement, and adds no extra size to your code bundle.
import { useRef } from 'react';
function EmailField() {
const inputRef = useRef(null);
function handleSubmit(e) {
e.preventDefault();
if (inputRef.current.reportValidity()) {
// at this point inputRef.current.value is syntactically valid
}
}
return (
<form onSubmit={handleSubmit} noValidate>
<input ref={inputRef} type="email" required />
<button>Save</button>
</form>
);
}
Hand-Rolled Regex in the Component
This technique defines a custom regular expression inside your component to check the email format. The state of the input field and any potential error message are managed with the "useState" hook. A constant, "EMAIL_RE", holds the regex pattern.
Validation logic executes on the "onBlur" event, which fires when the user navigates away from the input field. The "test()" method of the regex evaluates the email string. If the string fails the test, an error message is set and displayed. Otherwise, the error state is null. The pattern used is a common one found in many React tutorials.
import { useState } from 'react';
const EMAIL_RE = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
function InlineRegex() {
const [email, setEmail] = useState('');
const [error, setError] = useState(null);
function onBlur() {
setError(EMAIL_RE.test(email) ? null : 'Invalid e-mail');
}
return (
<>
<input value={email} onChange={e => setEmail(e.target.value)}
onBlur={onBlur} />
{error && <span>{error}</span>}
</>
);
}
React-Hook-Form with a Pattern Rule
The "react-hook-form" library offers a declarative way to handle form validation. The "useForm" hook provides a "register" function to connect inputs to the form state and a "formState" object that contains any validation errors. You pass validation rules, such as "required" and "pattern", to the "register" function.
The "pattern" rule accepts a regular expression and a custom error message. A key benefit of this library is its performance. It validates only the fields that change, which avoids unnecessary renders. Errors are accessible through the "errors" object and can be conditionally displayed.
import { useForm } from 'react-hook-form';
function HookForm() {
const { register, handleSubmit, formState:{ errors } } = useForm();
return (
<form onSubmit={handleSubmit(console.log)}>
<input
{...register('email', {
required: 'E-mail is required',
pattern : {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: 'Invalid e-mail'
}
})}
/>
{errors.email?.message}
<button>Go</button>
</form>
);
}
External Validation Library
Another option is to use a dedicated validation library like "validator.js". These libraries abstract away the complexity of regex patterns by providing simple functions. For example, "validator.js" has an "isEmail()" function that checks if a string conforms to the standard email format.
As some guides show, you first install the package with 'npm install validator'. Then, you can import and use the "isEmail" function directly in your event handlers, such as "onChange". The function returns a boolean, which you can use to conditionally set and display a validation message.
import validator from 'validator';
import { useState } from 'react';
function ValidatorLib() {
const [msg, setMsg] = useState('');
return (
<>
<input onChange={e =>
setMsg(validator.isEmail(e.target.value)
? '✓'
: 'Enter a valid e-mail')
} />
<span>{msg}</span>
</>
);
}
Challenges of Email Validation in React
While the methods above seem straightforward, they introduce significant hurdles. These approaches often fall short of comprehensive verification and create complexities for both developers and end-users.
- A regex that fully complies with email standards is extremely complex and hard to maintain. Simpler patterns, like those in hand-rolled or hook-form solutions, often reject valid emails or accept invalid ones, which creates a poor user experience.
- Browser constraint-validation via type="email" is unreliable. The HTML5 specification is loose, so different browsers validate addresses inconsistently. This leads to unpredictable behavior and error messages that you cannot easily control or style.
- React's asynchronous state updates complicate validation logic. `setState` batches changes, so handlers might read stale input values. This can cause validation to pass on the client but fail on the server, which creates hard-to-debug edge cases.
- All front-end methods, from regex to external libraries, only check syntax. They cannot confirm if an email address actually exists or can receive mail. True deliverability verification requires network calls to check DNS and SMTP records from a server.
Validate Emails with Abstract API
Build a more reliable React app by implementing email validation to catch invalid user entries.
Get started for free
How Abstract API Handles Email Validation in React
Abstract API addresses the core weaknesses of traditional methods because it off-loads all complex validation to its servers.
- It performs a live SMTP handshake, checks for disposable domains, and detects catch-all addresses.
- The API provides a quality score from 0.01 to 0.99 and offers typo corrections for user inputs.
- Developers receive a clear JSON response with a deliverability status and specific flags for role, free, or disposable emails.
- This approach removes the need for direct SMTP traffic from the browser and eliminates outdated regex logic.
How to Add Abstract API to Your Dev Environment
Once you are familiar with Abstract’s capabilities, the addition of its email validation API to your project is simple.
- Sign up at Abstract, create an Email Validation workspace, and copy the API key.
- Install axios with the command `npm install axios`.
- Add your API key to a `.env` file with the variable `REACT_APP_ABSTRACT_EMAIL_KEY` and restart your development server.
- Create a `validateEmail.js` file that calls the API endpoint.
- Import the `validateEmail` function into your form component and call it on blur or submit events.
- Use the response fields, such as `deliverability` and `quality_score`, to drive UI logic and error states.
// validateEmail.js
import axios from 'axios';
const API_KEY = process.env.REACT_APP_ABSTRACT_EMAIL_KEY;
const base = `https://emailvalidation.abstractapi.com/v1/?api_key=${API_KEY}`;
export async function validateEmail(email) {
const { data } = await axios.get(`${base}&email=${encodeURIComponent(email)}`);
return data;
}
Sample Email Validation Implementation with Abstract API
The code below shows a simple form submission handler. It calls the `validateEmail` function with the user's input. If the API response shows the email is "DELIVERABLE" and has a quality score above 0.8, the form submission proceeds. Otherwise, it displays an error, with a suggestion from the `autocorrect` field if available.
// EmailInput.jsx (Form library agnostic)
const handleSubmit = async value => {
const res = await validateEmail(value);
if (res.deliverability === 'DELIVERABLE' && res.quality_score > 0.8) proceed();
else showError(res.autocorrect || 'Email not deliverable');
};
The API returns a clear JSON object that gives you immediate data points for your UI. The `deliverability` and `quality_score` fields allow a quick go or no-go decision. Other boolean flags like `is_disposable_email` or `is_role_email` let you enforce specific business rules, while `is_mx_found` and `is_smtp_valid` confirm the domain and mailbox exist—checks that are impossible to perform from the browser.
{
"email":"johnsmith@gmail.com",
"autocorrect":"",
"deliverability":"DELIVERABLE",
"quality_score":0.9,
"is_valid_format":{"value":true,"text":"TRUE"},
"is_free_email":{"value":true,"text":"TRUE"},
"is_disposable_email":{"value":false,"text":"FALSE"},
"is_role_email":{"value":false,"text":"FALSE"},
"is_catchall_email":{"value":false,"text":"FALSE"},
"is_mx_found":{"value":true,"text":"TRUE"},
"is_smtp_valid":{"value":true,"text":"TRUE"}
}
Final Thoughts
Traditional client-side checks often miss critical issues like disposable domains and fail to perform live SMTP handshakes. Abstract API solves this by the movement of complex validation to its servers, which returns a detailed and actionable response. To reliably validate user emails, consider the creation of an account on Abstract API for a free API key.
Validate Emails with Abstract API
Implement proper email validation in your React app to ensure data accuracy and user trust.
Get started for free