React-Native TextInput For Phone Numbers
--
React-Native doesn’t have types the same way input in JavaScript has. After looking at react-native-phone-input and seeing that the library isn’t kept up and has a lot of unresolved issues. I decided to build it out myself with React-hooks, react-native-picker and libphonenumber-js. I hope this could be helpful if you want to follow my route.
First install the libraries npm install @react-native-community/picker — save
oryarn add @react-native-community/picker
thencd ios/ && pod install
npm install libphonenumber-js --save
oryarn add libphonenumber-js
The code I used to make a sample app
What the App.js
looks like:
Here is the code for CountryCodes.js
(just to clean up the code a little):
Now let’s go over it
useEffect(() => {
if (text.length > 0) setTextSize(18)
else if (text.length === 0) setTextSize(15)
}, [text])
This is just a styling with conditional rendering. Every time text is updated it checks to see if text
is empty and changes the textSize
so that the placeholder font size is different.
const onTextChange = (number) => {
const num = parsePhoneNumberFromString(number, CountryCodeKey[code][0])
let reg = /^[0-9]/
if (!!num && text.length > number.length && !reg.test(text[text.length - 1])){
let phone = num.nationalNumber.split('')
phone.pop()
phone = phone.join('')
setText(phone)
} else {
setText(new AsYouType(CountryCodeKey[code][0]).input(number))
}
}
onTextChange
is the function that updates text state so that you have a controlled form.setText(new AsYouType(CountryCodeKey[code][0]).input(number))
AsYouType allows only numbers to be typed and formats it according to the Country Calling Code (that is passed in with the code they choose). CountryCodeKey
is an Object for looking up the correct country code and you pass in the code
which is update by the picker.
Since it is formatted according to the Country Calling Code. If for example you have selected the US +1 and you started typing 555 by the third number it will have formatted to the area code (555). This causes an issue, if you try to delete it with Backspace, it will delete the ‘)’ but reformat the number so that its back to (555).
So I create a condition to check if you are deleting and whether it isn’t a number. Which if true deletes the number.const num = parsePhoneNumberFromString(number, CountryCodeKey[code][0])
returns a phone Object. let reg = /^[0–9]/
the RegExp to test if isn’t a number.
if (!!num && text.length > number.length && !reg.test(text[text.length — 1]))
checks to see if num exists, the input is smaller than the text
state (and therefore is deleting) and finally that it’s not a number.let phone = num.nationalNumber.split(‘’)
phone.pop()
phone = phone.join(‘’)
setText(phone)
Gets the phone number from the phone Object and removes the last number.
const signInWithPhone = () => {
const num = parsePhoneNumberFromString(text, CountryCodeKey[code][0])
if (!!num && num.isPossible()){
console.log('Phone Number', num.number)
} else {
alert('Please enter a valid phone number')
}
}
We get the phone Object from the text. num.isPossible()
is a method that checks to see if the phone number is the correct length. There is another method that you can use num.isValid()
that checks the number against RegExp to see if the number is valid. If it isn’t a phone number it alerts the user to enter a valid phone number.
One last thing make sure that in your TextInput
you have keyboardType=’phone-pad’
so that the keyboard type is that of a phone.
I hope this helps you in your own projects. Happy coding!