React Native Phone Number Verification

Last Updated May 31, 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:

Phone validation is the process of determining whether phone numbers that users input into your app are valid phone numbers. A valid number is the right length, is formatted properly, doesn’t contain unexpected characters, and can be verified as a current and active number. 

If you're building a React Native application, phone authentication is easy. React Native is a Javascript framework that allows you to build apps for iOS, Android, Windows, and other platforms using the same React JS code you already know and love. The best part is you can use many of the same libraries that you would use to build a React app, including phone authentication libraries.

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

Phone Verification in a React Native Application

This article will explore setting up a basic phone input with phone authentication in React Native. We'll build a React app running on iOS, using Native Components and react-native-phone-input. For validation, we’ll look at two methods: the provided isValidNumber method from the React Native package, and a dedicated phone validation API from AbstractAPI.

Prerequisites

This article will not teach you how to use React JS or React Native. If you’re not already familiar with React JS, we recommend checking out the ReactJS docs to get started.

If you're unfamiliar with React Native, we recommend using Expo to get started with React Native. Expo is to React Native what Create React App is to React. It helps you get a React Native dev environment up and running without writing a lot of boilerplate or installing a lot of tools.

You will need to install the Expo Go app on an iOS device. This tutorial won’t dive into specifics of how to get started with Expo or Expo Go—for more detail on that, check out the Expo docs.

Get Started

Use the Expo command-line interface to spin up your phone verification application. This is kind of like running npx create-react-app for a React JS app. If you are not using expo, you would run react native init to run the React Native Application instead.


$ expo init react-native-phone-number-validation
$ cd react-native-phone-number-validation

We’ll be working with Native Components, which are part of the React Native Core library. We’ll also be using an NPM package to build the actual phone input, so let’s install that too.


$ npm install –-save react-native-phone-input

To check that things are working, let’s start up the app.


$ expo start

This command tells Expo to start the Metro bundler, which compiles and bundles the code and serves it to the Expo Go app. Scan the QR code in your console using the phone’s camera to connect to the Metro bundler. This will open up the app on your phone.



That’s it! Our simple React Native app is now up and running.

Build a Phone Number Input With Native Components

Create the PhoneNumberInput Component

Create a new file next to App.js called PhoneNumberInput.js. We’ll put all the form and validation logic in this file and render the component here. Inside the file, create a PhoneNumberInput component.

 
import React, { useState, useRef } from "react";
import { SafeAreaView, StyleSheet, Text, TouchableHighlight } from "react-native";
import PhoneInput from "react-native-phone-input";
 
const PhoneNumberInput = () => {
  const [phoneNumber, setPhoneNumber] = useState("");
   const phoneInput = useRef<PhoneInput>(null);
 
 
  const handleSubmit = () => {
   // we’ll write this next
  }
  return (
    <SafeAreaView>
          <PhoneInput
               style={styles.phoneInput}
               initialValue={phoneNumber}
               initialCountry="us"
               onChangeText={(text) => {
                   setPhoneNumber(text);
               }}
               withShadow
               autoFocus
           />
      <TouchableHighlight onPress={handleSubmit}>
         <Text>Submit</Text>
      </TouchableHighlight>
   </SafeAreaView>
  )
}
const styles = StyleSheet.create({
   phoneInput: {
       borderWidth: 1,
       borderRadius: 25,
       width: 250,
       height: 50,
       padding: 5,
   },
  button: {
      borderWidth: 1,
      borderColor: 'green',
      borderRadius: 15,
      marginTop: 25,
      padding: 10,
      alignItems: 'center'
  },
});
export default PhoneNumberInput;

We’ve used the useState hook to set the initial phoneNumber to an empty string and passed that to the PhoneNumberInput component as its defaultValue prop. The onChangeText handler will update the phone number in state to the inputted value.

Next, we scaffolded out a handleSubmit function that will be called when the user taps the “Submit” button. That is where we will put our validation logic too.

You’ll notice that the PhoneNumberInput uses a ref. This is used to do validation through a isValidNumber method that the package provides. If you’re not sure how to use refs, check out this tutorial.

We’ve used the SafeAreaView component to make sure the form renders in the correct place on the mobile screen, and we’ve added some basic styling using the StyleSheet component.

Next, we’ll write the handleSubmit function, which will validate the email input before submitting it.

Add Validation Logic

Our handleSubmit function will pull the phoneNumber value out of state, validate it, and then—as long as validation is successful—submit the email to our server (for now, we’re actually just logging the value to the console.)

We’ll look at two methods of validation: using the isValidNumber method provided by the NPM phone input package, and sending the number to AbstractAPI’s Free Phone Number Validation endpoint.

Use the isValidNumber Method

The NPM package we get the phone input component from comes with a handy validation method to check a number’s length and formatting. To use it, grab the phoneInput ref we created earlier, access the ref’s current value, and call the function.


  const handleSubmit = (phoneNumber) => {
       const isValid = phoneInput.current?.isValidNumber(phoneNumber);
       if (isValid) {
           console.log("SUBMITTED! ", phoneNumber)
       } else {
           console.log("INVALID NUMBER.")
       }
   }


Use AbstractAPI’s Phone Validation Endpoint

If you want more information than this validation method provides, or if you’d rather not use a React ref hook (they can be notoriously tricky to work with) you can use the AbstractAPI Phone Validation endpoint instead.

Acquire an API Key

Go to the Phone Validation API Get Started page and click the blue “Get Started” button.


You’ll need to either sign up or log in. Once you’ve done that, you’ll be taken to the API’s homepage, where you’ll see options for documentation, pricing, and support, and you’ll see your API key. 

Each Abstract API has a unique key, so even if you’ve used another Abstract API before, this key will be unique. Don’t attempt to use a different AbstractAPI key.

Send a Request to the API

React Native uses the Fetch API to send and receive HTTP requests. 

Let’s write a function called sendPhoneNumberValidationRequest to send the request to the API endpoint using Fetch.


const apiKey = 'YOUR_API_KEY';
const apiURL = 'https://phonevalidation.abstractapi.com/v1/' + apiKey;
...
   const sendPhoneNumberValidationRequest = async (phoneNumber) => {
       try {
           const response = await fetch.get(apiURL + '&phone_number=' + phoneNumber);
           console.log(response.json())
       } catch (error) {
           throw error;
       }
   }

Don’t forget to call .json() on the response to parse it correctly. The data inside the response should look something 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."
}


For now, the only part we’re interested in is the valid boolean value. We’ll return this value from our sendPhoneNumberValidationRequest function. 

           const response = await fetch.get(apiURL + '&phone_number=' + phoneNumber);
           const data = response.json();
           return data.valid;

Use the Validation Response in the handleSubmit Function

Now that we have our response from the API, let’s put it into our handleSubmit function. Remove the previous validation check that we did with the isValidNumber method. You can also remove any code referring to the useRef hook and the ref itself.

   const handleSubmit = async (phoneNumber) => {
       const isValid = await sendPhoneNumberValidationRequest(phoneNumber);
       if (isValid) {
           console.log("SUBMITTED! ", phoneNumber);
       } else {
           console.log("INVALID NUMBER.");
       }
       return isValid;
   }

import React, { useState, useRef } from "react"; // remove useRef
...
   const phoneInput = useRef<PhoneInput>(null); //remove this
...
           ref={phoneInput} // remove this


Note that we turned our handleSubmit function into an async function because we are now making an API call to validate the number.

Render the Form in App.js

Remove everything between the outermost <div> elements inside App.js. Import your new phone number input and render that React component instead.


import { StatusBar } from 'expo-status-bar';
import { StyleSheet, View } from 'react-native';
import PhoneNumberInput from './PhoneNumber;
 
export default function App() {
 return (
   <View style={styles.container}>
     <PhoneNumberInput/>
     <StatusBar style="auto" />
   </View>
 );
}
 
const styles = StyleSheet.create({
 container: {
   flex: 1,
   backgroundColor: '#fff',
   alignItems: 'center',
   justifyContent: 'center',
 },
});


Visit the Expo Go app again. Your new input should be rendered!



Error Handling

If phone number validation fails, or if something else goes wrong while the request is being sent to the API, we need to let the user know. Let’s render an error message to tell the user what went wrong.

   const [errorMessage, setErrorMessage] = useState("");
...
   const handleSubmit = async (phoneNumber) => {
       try {
           const isValid = await sendPhoneNumberValidationRequest(phoneNumber);
           if (isValid) {
               setErrorMessage("");
               console.log("SUBMITTED! ", phoneNumber);
           } else {
               setErrorMessage("INVALID PHONE NUMBER.PLEASE CHECK YOUR INPUT AND TRY AGAIN.");
               console.log("INVALID NUMBER.");
           }
           return isValid;
       } catch (error) {
           setErrorMessage("COULD NOT VALIDATE PHONE NUMBER.PLEASE TRY AGAIN LATER.");
       }
   }

We created an errorMessage value in state, and initialized it to and empty string. Then, if the response that comes back from the API is valid: false, we update the state with an error message to let the user know the phone number is invalid.

We also added some better error handling around the async/await code to  handle network failures and other errors. We wrapped the HTTP request in a try/catch block so that if anything goes wrong, we catch the error and display an error message to the user.

The last thing we need to do is render the errorMessage so the user can see it. We’ll use the React Native <Text/> component to do this.

...    
       <TouchableHighlight onPress={handleSubmit} style={styles.button}>
         <Text>Submit</Text>
       </TouchableHighlight>
   <Text style={styles.error}>{errorMessage}</Text> // added this
...
const styles = StyleSheet.create({
   button: {
       borderWidth: 1,
       borderColor: 'green',
       borderRadius: 15,
       marginTop: 25,
       padding: 10,
       alignItems: 'center'
   },
   error: {
       color: 'red' // added this
   }
});

 


Put it All Together

Let’s take a look at the complete code for our PhoneNumberInput React component, including error handling.

import React, { useState } from "react";
import { SafeAreaView, TouchableHighlight, Text, StyleSheet } from "react-native";
import PhoneInput from "react-native-phone-input";
 
const apiKey = 'YOUR_API_KEY';
const apiURL = 'https://phonevalidation.abstractapi.com/v1/' + apiKey
const PhoneNumberInput = () => {
   const [phoneNumber, setPhoneNumber] = useState("");
   const [errorMessage, setErrorMessage] = useState("");
 
 
   const handleSubmit = async (phoneNumber) => {
       try {
           const isValid = await sendPhoneNumberValidationRequest(phoneNumber);
           if (isValid) {
               setErrorMessage("");
               console.log("SUBMITTED! ", phoneNumber);
           } else {
               setErrorMessage("Invalid phone number. Please try again.");
               console.log("INVALID NUMBER.");
           }
           return isValid;
       } catch (error) {
           setErrorMessage("SOMETHING WENT WRONG.PLEASE TRY AGAIN LATER.");
       }
   }
  
   const sendPhoneNumberValidationRequest = async (phoneNumber) => {
       try {
           const response = await fetch.get(apiURL + '&phone_number=' + phoneNumber);
           const data = response.json();
           return data.is_valid_format.value;
       } catch (error) {
           throw error;
       }
   }
 
  return (
    <SafeAreaView>
          <PhoneInput
               style={styles.phoneInput}
               initialValue={phoneNumber}
               initialCountry="us"
               onChangeText={(text) => {
                   setPhoneNumber(text);
               }}
           />
       <TouchableHighlight onPress={handleSubmit} style={styles.button}>
         <Text>Submit</Text>
       </TouchableHighlight>
       <Text style={styles.error}>{errorMessage}</Text>
   </SafeAreaView>
  )
}
const styles = StyleSheet.create({
   phoneInput: {
       borderWidth: 1,
       borderRadius: 25,
       width: 250,
       height: 50,
       padding: 5,
   },
   button: {
       borderWidth: 1,
       borderColor: 'green',
       borderRadius: 15,
       marginTop: 25,
       padding: 10,
       alignItems: 'center'
   },
   error: {
       color: 'red'
   }
});
 
export default PhoneNumberInput;


Type an invalid phone number into the input and click “Submit.” The sendPhoneNumberVerification function sends a request to the API, which will come back false. Our error handling logic then sets the errorMessage value and renders an error message.

Conclusion

That was a basic overview of setting up a simple phone number input with validation in React Native. There’s a lot more that can be done to improve this. For example, we can customize the style of the input and add a loading spinner while the handleSubmit function is running to let the user know the app is busy.

FAQs

What is useRef in React?

The useRef hook is a React hook that allows you to create a reference to a component in the component tree. Using the .current value of the ref, you can access the component inside your app logic.

The most important things to remember about a ref are that the value of it is persisted between renderings (meaning, it doesn’t change when the component re-renders), and that updating a ref doesn’t trigger a re-render.

Refs can be tricky to work with. We recommend reading up on them here.

How Do I Validate a Phone Number in React Native?

There are many ways phone authentication in React Native. A very simple way is to use a package that provides an out-of-the-box validation method. You could also use a dedicated third-party phone authentication API like AbstractAPI’s Free Phone Number Validation API.

How Do You Validate in React Native?

Performing validation in React Native is similar to doing validation in React JS. Depending on what you are trying to validate, you need to grab the string, number, or whatever the user input is from the state. Then, you run a validation function against the input. In the case of a phone number, you might do phone authentication by checking that the number is the right length and that it is properly formatted, using a RegEx matcher, a third-party library, or a validation API. 

Validate phone numbers instantly using Abstract's API.

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