Guides
Last updated
July 25, 2025

5 Ways to Implement Phone Number Validation in React

Nicolas Rios
Nicolas Rios
Table of Contents:
ON THIS PAGE
Get your free
phone validation
 API key now
stars rating
4.8 from 1,863 votes
See why the best developers build on Abstract
START FOR FREE
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
No credit card required

Ensuring phone numbers are valid is a basic requirement for data quality in any React application. We'll look at five different ways to build this validation, providing working code for each. You'll also learn about the shortcomings of traditional methods and see how Abstract API solves these problems.

How to Implement Phone Number Validation in React

Here are four common methods to validate phone numbers in a React application. Each approach has a different implementation, from native HTML attributes to comprehensive component libraries.

HTML Constraint Validation

This method uses the browser’s built-in validation engine, which keeps the implementation simple and outside of React's direct control. The form remains uncontrolled, and React only interacts with the validation API when needed.

The "pattern" attribute delegates the parsing logic to the browser’s Constraint Validation API. React’s "ref" provides direct access to the input element’s methods, such as "checkValidity" and "reportValidity". This approach also ensures the component is tree-shake friendly.

The code creates a form with a "tel" input. The "onSubmit" function checks the input's validity and calls "reportValidity" to display a native error tooltip if the check fails.

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 or with a schema library like Yup or Zod. This approach is synchronous, tree-shakable, and works in any validation library that supports a "test" or "refine" function.

The canonical E.164 expression is a common choice for this. The code implements a controlled component where the input's value is stored in the component's state. The "onChange" handler updates the state and uses the regex "test" method to check the value. If the validation fails, an error message is set and displayed.

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 technique uses Google’s phone number metadata for precise validation, including exact length ranges and number type rules. When paired with React Hook Form, you can integrate this logic efficiently without extra component rerenders.

The libphonenumber-js library is the same engine that powers other popular tools. It can also format on the fly.

The code shows how to use the "useForm" hook to manage form state. A custom "validate" function uses "parsePhoneNumberFromString" from the library to check the input. If the number is invalid, it returns an error message that React Hook Form then displays.

import { parsePhoneNumberFromString } from 'libphonenumber-js/max';   // full metadata
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

Another option is to install a complete UI component that bundles an input field, flag dropdown, number formatting, and validation logic. The react-phone-number-input library is a popular example that wraps "libphonenumber-js".

It exposes a helper function called "isValidPhoneNumber" while it also handles input masks and country selection. For non-React projects, intl-tel-input offers a similar user experience.

The code demonstrates how to use the "PhoneInput" component. Its value is managed with React state, and the "isValidPhoneNumber" function is used to conditionally show an error message.

import PhoneInput, { isValidPhoneNumber } from 'react-phone-number-input';
import 'react-phone-number-input/style.css';           // 15 kB 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

Traditional validation methods in React often introduce problems with bundle size, maintenance, and user experience. These approaches struggle with the fluid nature of global phone number standards.

  • Global numbering plans constantly evolve. Methods that use libphonenumber-js require large metadata bundles that inflate app size. A stale bundle produces false positives or negatives until you redeploy the app with the latest rule updates.
  • Users enter numbers with varied formats like spaces and dashes. Simple regex or HTML pattern attributes fail to parse these variations, as one number can have many legal spellings. This demands extra logic for proper normalization.
  • Turn-key UI components often miss edge cases. Some fail to format numbers for certain countries, render incorrectly in RTL layouts, or misinterpret numbers that lack a country code. This creates an unreliable user experience.
  • Controlled components trigger validation on every keystroke, which flags incomplete numbers as invalid. Without a debounce strategy, this creates a poor user experience and can introduce complex state management issues or race conditions.

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 by performing real-time, server-side checks instead of simple pattern matches.

  • It conducts real-time, server-side checks against current numbering datasets for more than 195 countries. The API returns details like validity, format, carrier, line type, and region, which offers more depth than simple pattern matches.
  • The API removes the need to manually curate validation rules. This allows developers to gate critical workflows, like multi-factor authentication, on an authoritative response.
  • As a lightweight REST endpoint, it avoids the addition of heavy libraries to the client. This approach keeps the React bundle small and moves sensitive logic off the user's device.

How to Bring Abstract API to Your Dev Environment

Once you're familiar with Abstract’s capabilities, adding its phone number validation API to your project is simple.

  • First, sign up at Abstract API, create a Phone Validation instance, and copy your API key.
  • Next, install the Axios library in your React project to handle HTTP requests.
  • Then, add an environment variable, such as REACT_APP_ABSTRACT_KEY, to securely store your API key.

After the setup, create a utility function to call the API:

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 API returns a detailed JSON object. A "true" value for the "valid" field confirms the number exists and is reachable. The "format" object provides strings ready for display in your user interface. Other fields like "country", "location", "type", and "carrier" allow you to enforce geographic rules or build fraud detection logic.

Here is a sample response for a valid U.S. phone number:

{
  "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 validation methods often use regular expressions that only check a number's format. They cannot confirm if a number is real or in service, which creates gaps in data quality and security.

Abstract API closes these gaps with real-time checks against carrier data. For reliable phone number validation, consider creation of an account on Abstract API to get your free 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

Related Articles

Phone Validation
key now
Get your free
stars rating
4.8 from 1,863 votes
See why the best developers build on Abstract
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
No credit card required