Phone number validation is a common requirement for React applications to ensure data quality. We will explore five different ways to implement it, complete with working code snippets. We'll also examine the pitfalls of common approaches and see how Abstract API effectively addresses these challenges.
How to Implement Phone Number Validation in React
Here are four common ways to add phone number validation to a React application. Each method has a different implementation, from native browser features to specialized component libraries.
HTML Constraint Validation
This approach uses the browser’s built-in validation engine. The form remains uncontrolled, which means React does not manage its state. React only calls the API upon submission.
The `pattern` attribute delegates the validation logic to the browser's Constraint Validation API. A React ref provides direct access to the input element's `checkValidity` and `reportValidity` methods. This keeps the component tree-shake friendly as it adds no extra runtime.
function NativeTel() {
const inputRef = React.useRef(null);
const onSubmit = e => {
e.preventDefault();
const field = inputRef.current;
if (field.checkValidity()) {
/* go ahead – value is field.value */
} else {
field.reportValidity(); // native tooltip
}
};
return (
<form onSubmit={onSubmit}>
{/* E.164 skeleton: optional “+”, 10–15 digits */}
<input
type="tel"
ref={inputRef}
pattern="^\+?[1-9]\d{9,14}$"
required
/>
<button type="submit">Save</button>
</form>
);
}
Custom Regular Expression
You can run a regular expression inside a controlled component. This method also works well within schema validation libraries like Yup or Zod. The canonical E.164 expression is the same one Abstract API shows.
The code creates a controlled component where the input's value and any validation errors live in the React state. The `onChange` handler updates the state and uses the regex `test` method to validate the input. This approach is synchronous and tree-shakable.
const E164 = /^\+?[1-9]\d{9,14}$/;
function RegexTel() {
const [value, set] = React.useState('');
const [error, setError] = React.useState(null);
const onChange = e => {
const v = e.target.value;
set(v);
setError(!E164.test(v) ? 'Invalid phone' : null);
};
return (
<>
<input type="tel" value={value} onChange={onChange} />
{error && <span style={{color:'red'}}>{error}</span>}
</>
);
}
libphonenumber-js with React Hook Form
This method uses Google's phone number metadata for precise validation. It checks for exact length ranges, number type rules, and formatting. React Hook Form allows you to plug in this logic without extra component rerenders.
The code imports `parsePhoneNumberFromString` from the libphonenumber-js library. A custom `validate` function checks if the parsed number is valid. This function is then passed to the `register` method from `useForm`. This library is the same engine that powers other popular components and can also format on the fly.
import { parsePhoneNumberFromString } from 'libphonenumber-js/max';
import { useForm } from 'react-hook-form';
function LibPhoneTel() {
const { register, handleSubmit, formState:{errors} } = useForm();
const validate = v => {
const p = parsePhoneNumberFromString(v);
return p?.isValid() || 'Bad phone';
};
const onSubmit = data => {/* data.phone is E.164 */};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('phone', { validate })} />
{errors.phone && <span>{errors.phone.message}</span>}
<button>Go</button>
</form>
);
}
Turn-key UI Components
You can install a component that provides an input, flag dropdown, formatting, and validation out of the box. The example uses react-phone-number-input, which wraps `libphonenumber-js`.
The code shows how to use the `PhoneInput` component and its `isValidPhoneNumber` helper function for validation. For projects that do not use React, intl-tel-input offers a similar user experience through a JavaScript plugin and CSS bundle.
import PhoneInput, { isValidPhoneNumber } from 'react-phone-number-input';
import 'react-phone-number-input/style.css';
function ComponentTel() {
const [value, setValue] = React.useState('');
return (
<>
<PhoneInput value={value} onChange={setValue} defaultCountry="US" />
{value && !isValidPhoneNumber(value) && 'Bad phone'}
</>
);
}
Challenges of Phone Number Validation
While the methods above seem straightforward, they introduce significant challenges that can compromise data quality and user experience. These pitfalls range from outdated information to poor implementation logic.
- Numbering plans change constantly. Libraries like libphonenumber-js require large, frequently updated metadata bundles for accuracy. A stale bundle produces false negatives and a poor user experience, while the large size impacts application performance.
- Users enter numbers with varied formats like spaces, dashes, and parentheses. Simple regex patterns in HTML constraint validation or custom hooks often fail to parse these variations correctly. This leads to either over-validation or under-validation of phone numbers.
- Turn-key components like react-phone-number-input can miss edge cases. They might fail to format numbers for certain countries, render incorrectly in RTL layouts, or misinterpret numbers that lack a country code. This compromises the user interface's reliability.
- Controlled components trigger validation on every keystroke. This flags incomplete numbers as invalid while the user types. Without a debounce strategy, this creates a frustrating user experience and can introduce race conditions with complex form libraries.
Validate Phone Numbers with Abstract API
Start validating phone numbers in your React app to improve data accuracy and user trust.
Get started for free
How Abstract API Handles Phone Number Validation in React
Abstract API addresses the core weaknesses of traditional methods. It performs real-time, server-side checks against constantly updated global numbering datasets.
- Traditional React validation depends on regex or client-side libraries. These approaches only confirm that a string matches a phone number pattern. They do not verify that the number exists, has a carrier, or remains in service.
- The API performs real-time checks against data for over 195 countries. It returns validity status, international and local formats, carrier, line type, and region. This provides far richer intelligence than simple pattern matches and removes the need for manual rule curation.
- As a lightweight REST endpoint, the API helps keep the React bundle small. It avoids the shipment of heavy libraries to the client. Privacy-sensitive logic also remains off the user's device.
How to Add Abstract API to Your Dev Environment
Once you know Abstract’s capabilities, you can add its phone number validation API to your project with ease.
- First, sign up at Abstract API, create a Phone Validation instance, and copy your API key.
- In your React project, run the command npm i axios, or use the native fetch API.
- Add an environment variable, like REACT_APP_ABSTRACT_KEY, to keep your credentials out of the source code.
- Create a utility function to handle the API call.
- Call this function inside your form’s onSubmit handler, not on every keystroke, to manage API requests efficiently.
- Optionally, cache or debounce calls to stay within the free-tier rate limits.
import axios from 'axios';
export async function validatePhone(phone) {
const { data } = await axios.get('https://phonevalidation.abstractapi.com/v1/', {
params: { phone, api_key: process.env.REACT_APP_ABSTRACT_KEY },
});
return data;
}
Sample Phone Number Validation with Abstract API
The validatePhone function sends a phone number to the Abstract API endpoint. The API processes the number and returns a detailed JSON object. This response provides much more than a simple true or false result. It contains actionable data you can use directly in your application logic.
The valid field confirms if the number is real and reachable. The format object gives you display-ready local and international versions. Other fields like country, location, type, and carrier let you enforce geographic rules or assess risk. For example, you can block a VOIP number if you require SMS for two-factor authentication.
{
"phone": "14152007986",
"valid": true,
"format": { "international": "+14152007986", "local": "(415) 200-7986" },
"country": { "code": "US", "name": "United States", "prefix": "+1" },
"location": "California",
"type": "mobile",
"carrier": "T-Mobile USA, Inc."
}
Final Thoughts
Traditional methods only check a number’s format, not its status. This leaves apps open to fake or inactive numbers. Abstract API solves this with real-time checks against live carrier data. To reliably validate user phone numbers, create a free account on Abstract API and get your API key.
Validate Phone Numbers with Abstract API
Implement phone number validation in your React app to prevent fake sign-ups and clean data.
Get started for free