React Phone Number Validation RegEx

Last Updated Jun 21, 2022
Elizabeth (Lizzie) Shipton

Lizzie is a Full Stack Engineer at Udacity and freelance technical content writer. She has experience working with Node, GraphQL, Postgres, React and Sass.

Table of Contents:

If you’re building a React application, you’re probably going to have to do some phone number validation at some point. Phone numbers are not only one of the most efficient ways of logging a user into your app, but they are also one of the most secure.

When you authenticate users via their mobile numbers in your React app, you’ll need to go through several steps to validate and verify those numbers. The first step is validating that the number a user has entered is a valid mobile number. A valid phone number is properly formatted, doesn’t contain any unexpected characters, and is a currently active phone number.

A very simple way to validate phone numbers in React is to use Regex to parse and match the string. Although the method is very simple, it’s also not terribly robust, so as well as looking at Regex in this tutorial, we’ll also take a look at a more resilient way of validating a phone number using AbstractAPI’s free phone number validator.

Don't reinvent the wheel.
Abstract's APIs are production-ready now.

Abstract's suite of API's are built to save you time. You don't need to be an expert in email validation, IP geolocation, etc. Just focus on writing code that's actually valuable for your app or business, and we'll handle the rest.

Get started for free

How to Validate a Phone Number Using Regex

We’re going to use react-phone-number-input, an NPM package that provides out-of-the-box components for phone number inputs, along with some handy methods for phone number validation.

We’ll also use React Hook Form, a library that uses React Hooks to make building forms and managing form state easy.

Create a React app and Install Dependencies

We’ll assume that you already have a basic understanding of React and Create React App. If you don't, check out this tutorial on React, and this information on Create React App before proceeding. 

To spin up a new app using Create React App


$ npx create-react-app react-phone-validation-app
$ cd react-phone-validation-app

Install react-phone-number-input and react-hook-form.


$ npm install react-phone-number-input
$ npm install react-hook-form 

And start the app


$ npm start

This will open a new browser window with the app running at http://localhost:3000.

Build the Input

Inside src create a new file called regex-phone-number-input.js and import your dependencies. Create a React Component called RegexPhoneNumberInput and for now, just render some text.


import React from "react";
import { useForm, Controller } from "react-hook-form";
import PhoneInput, { isValidPhoneNumber } from "react-phone-number-input";
import "react-phone-number-input/style.css";
 
const RegexPhoneNumberInput = () => {
return (
  		

This is where our phone input will go

); }; export default RegexPhoneNumberInput;

Remove the boilerplate between the two <header>s in App.js, import your new RegexPhoneNumberInput and render it instead.


import './App.css';
import PhoneNumberInput from './phone-number-input';
 
function App() {
 return (
   
); } export default App;

Check out your browser window at http localhost 3000. You should now see something like this:

That’s all we need to scaffold our app. Now let’s build the input. 

Add the Input Component

Inside the RegexPhoneNumberInput, add the React Hook Form wrapper using the components and handlers that React Hook Form provides. Use the onSubmit method to mock out a function that submits the data. For now, just log it to the console.


const {
  handleSubmit,
  formState: { errors },
  control
} = useForm();
 
const onSubmit = (data) => {
  console.log({data});
};

The useFormReact hook gives us a handleSubmit function, which must be passed to the onSubmit handler of the <form> element, and it will be called when the user submits the form. We pass our custom onSubmit function as an argument to handleSubmit.

Delete the <div> with the text and add the form element, a <label> and the React Hook form <Controller>


const RegexPhoneNumberInput = () => {
 
   const {
     handleSubmit,
     formState: { errors },
     control
   } = useForm();
 
   const onSubmit = (data) => {
     console.log({data});
   };
 
   return (
         <form onSubmit={handleSubmit(onSubmit)} className="user-info-form">
           <div>
               <label htmlFor="phone-input">Phone Number</label>
               <Controller
               name="phone-input"
               control={control}
               render={({ field: { onChange, value } }) => (
                 // this is where our react-phone-number-input will go
               )}
               />
           </div>
         </form>
   );
};

Notice that we name our controller “phone-input” (this will be important when we handle errors.) We pass the control prop from the useForm hook to the <Controller>

We’ve now set up the React Hook Form logic that helps us handle the form state. The render field on the <Controller> is where the actual phone input will be rendered. Let’s add that now using react-phone-number-input.

The render field takes a function that returns a child component. The function accepts one argument, the field object, which passes to the child component an onChange handler and the field’s value.

This takes a lot of the state management out of rendering the form. React Hook Form takes care of updating the state of the form, so we don’t have to write our own initial value, use setState, or write an onChange handler.

The component we’re returning is the react-phone-number-input PhoneInput component. Let’s check out our phone number app in the browser again.

We’re now rendering a complete phone number input. We just need to add our Regex validation.

Add validation logic

React Hook Form makes validation easy. We can use the rules field of the <Controller> component to run our validation function. We could also use the isValidPhoneNumber method provided by react-phone-number-input to validate the number, however, for the sake of this tutorial, we’ll write our own customer Regex validator.

Here’s the Regex we’ll be using to validate the string.


^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$

For a thorough breakdown of how this Regex works, click here. This will match phone numbers input in the following formats:


+919367788755
8989829304
+16308520397
786-307-3615
(786) 307-3615

Create a new Regular Expression using this string. Make it global, case insensitive, and multiline.


const PHONE_REGEX = 
               new RegExp(/"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"/gmi);

Create a handleValidate method that accepts a phone number and uses the Regex.test() method to check for a positive match against the provided string.


 const handleValidate = (phoneNumber) => {
   return PHONE_REGEX.test(phoneNumber);
 }

Now, we can just pass this custom validation function to our rules field on the <Controller>. React Hook Form will handle calling the validation function for us whenever the user updates the input.


              rules={{
                 validate: (value) => handleValidate(value)
               }}

Handle Errors

Now, we just need to show the user an error when they enter an invalid phone number. Luckily, React Hook Form makes this super easy as well. React Hook Form will catch any errors that arise from running the validation function we gave it.

React Hook Form gives us access to an errors object in the useForm hook. We can use that to track our errors and render a message if one exists.


   const {
     handleSubmit,
     formState: { errors },
     control
   } = useForm();

  const handleValidate = (phoneNumber) => {
   if (PHONE_REGEX.test(phoneNumber)) {
     errors["phoneNumber"] = null;
   } else {
     errors["phoneNumber"] = "Invalid phone number. Please try again."
   }
   return PHONE_REGEX.test(phoneNumber);
 }
   {!!errors.phoneNumber && 

{errors.phoneNumber}

}

Put It All Together

Here’s the full code for our phone number input component.


import React from "react";
import { useForm, Controller } from "react-hook-form";
import PhoneInput, { isValidPhoneNumber } from "react-phone-number-input";
import "react-phone-number-input/style.css";
 
const PHONE_REGEX = new RegExp(/"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"/gmi);
 
const RegexPhoneNumberInput = () => {
 
   const {
     handleSubmit,
     formState: { errors },
     control
   } = useForm();
   const onSubmit = (data) => {
     console.log({data});
   };
 
 const handleValidate = (phoneNumber) => {
   if (PHONE_REGEX.test(phoneNumber)) {
     errors["phoneNumber"] = null;
   } else {
     errors["phoneNumber"] = "Invalid phone number. Please try again."
   }
   return PHONE_REGEX.test(phoneNumber);
 }
 
   return (
         <form onSubmit={handleSubmit(onSubmit)} className="user-info-form">
           <div>
               <label htmlFor="phone-input">Phone Number</label>
               <Controller
               name="phone-input"
               control={control}
               rules={{
                 validate: (value) => handleValidate(value)
               }}
               render={({ field: { onChange, value } }) => (
                   <PhoneInput
                     value={value}
                     onChange={onChange}
                     defaultCountry="US"
                     id="phone-input"
                   />
               )}
               />
             {!!errors.phoneNumber && <p style={{color: 'red'}}>{errors.phoneNumber}</p>}
           </div>
         </form>
   );
};
export default RegexPhoneNumberInput;

Why You Shouldn’t Validate a Phone Number Using Regex

This is fine (kind of) if you’re only validating US numbers. You’re never going to be able to write a Regular Expression that matches every type of international phone number. Here are some common obstacles that rolling your own validator with Regex presents.

Phone Number Length

In the US, phone numbers are 10 digits long (when you include the area code.) In Mexico, a valid phone number is 12 digits long. In France, it’s 10. The maximum allowed length for an international phone number, according to the International Telecommunication Union (ITU) is 15 digits. 

Delimiters

Delimiters (the characters that separate the numbers in a phone number) are different all over the world. Similarly, the way numbers are grouped in a phone number differs from country to country. This is really difficult to capture in a Regula Expression. One solution is to strip out delimiters and whitespace before analyzing the phone number.

User Error

The final problem you commonly encounter with phone number inputs is user error. Some users include their country code when entering a phone number. Some users want to include delimiters and spaces while others don’t. Some will try to enter their area code, others will not.

Validation Through a Dedicated Library

A much better idea is to use a validation library or a dedicated phone number validation API. That way, the nitty-gritty of parsing, cleaning, and comparing a string of numbers is put on the library or API. All you have to do is collect the user’s number and pass it off to the validator. 

A great API for this is AbstractAPI’s free phone number validator. You can send any phone number to the API’s REST endpoint and get back a JSON object with a validation boolean and additional information about the number.

The object that AbstractAPI returns look like this:


{
  "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."
}

Let’s rewrite our handleValidate method to use the AbstractAPI phone validation endpoint instead of the Regex.

Acquire an API key

You’ll need an API key to use the AbstractAPI endpoint. Navigate to the API documentation page. You’ll see an example of the API’s JSON response object to the right, and a “Get Started” button to the left.

Click “Get Started.” You’ll be asked to create an account using your email and a password. If you already have an AbstractAPI account, you’ll be asked to log in. 

Every AbstractAPI API needs a unique key, so if you have an existing API key from a different API, you’ll be given a new one for this API. You’ll land on the API homepage.

Rewrite the Validation Using the API

We’ll first write a function that uses fetch to send a GET request to the API endpoint, with our API key and the phone number for validation.


const apiKey = 'YOUR_API_KEY';
const apiURL = 'https://phonevalidation.abstractapi.com/v1/?api_key=' + apiKey;

 async function sendValidationRequest(phoneNumber) {
   try {
     const response = await (await fetch(apiURL + "&pphone_number=" + phoneNumber)).json();
     return response.data.valid
   } catch (error) {
     throw error
   }
 }

We could call out sendValidationRequest method inside our handleValidate function instead of using the Regex validator. However, React Hook will call this validation function on every keystroke, meaning we’d be sending an AJAX request to the endpoint on every keystroke, and we’d quickly hit a 429 “Too many requests” error.

Instead, we’ll move the validation logic to the onSubmit function.


 const onSubmit = async (data) => {
   const isValid = await sendValidationRequest(data["phone-input"]);
   if (isValid) {
     errors["phoneNumber"] = null;
     console.log({data});
   } else {
     errors["phoneNumber"] = "Invalid phone number. Please try again."
   }
 };

We had to turn our onSubmit into an async function since we’re now sending a network request. The data will only be submitted if the API tells us the phone number is valid. Otherwise, we’ll display an error to our users.

We could remove the Regex validation from the form, or leave it in. It doesn’t hurt to have two levels of validation in a user form. 

Conclusion

Using React Hook Form and react-phone-number-input to validate phone numbers is easy. Regex is one option for validating the strings, however, it’s not recommended. Component libraries, state management systems, and validation APIs like Abstract API are much more reliable and robust ways of validating numbers.

FAQs

How do I validate a phone number in React?

There are many libraries that allow you to quickly build forms and handle form state and input validation. Two great libraries for handling phone number validation in a React application are react-phone-number-input and React Hook Form. Used together, these packages provide out-of-the-box validation methods and components for form building.

Another phone number validation method in React is to use a dedicated validation API. AbstractAPI’s Free Phone Number Validation API provides a secure REST endpoint to get validation and other information for any phone number.

How Does the AbstractAPI Phone Validator API Work?

The Phone Validator API checks the phone number against a set of databases that contain phone numbers from over 19 countries. No phone calls are made and no SMS messages are sent during the validation process. You can use the API to standardize numbers for your contact list and collect information about the user’s phone number, as well as check if the number is valid.

Why Do I Need to Verify a Phone Number?

Phone number verification and validation are two important steps in the process of onboarding and authenticating your users. Validation prevents a user from accidentally inputting a phone number with invalid characters or a phone number that doesn’t exist. Validation helps keep users’ identities and personal information secure and indicates explicit consent from the user that they allow the use of their phone number.

Validate phone numbers instantly using Abstract's phone verification API.

Get started for free
Validate phone numbers instantly using Abstract's phone verification API.
Get started