react-phone-number-input
react-phone-number-input copied to clipboard
(React Native) Can this package be used in the React Native?
Can this package be used in the react native
Update: Yes, "without country select" component.
First, create PhoneTextInput.js file:
import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import { TextInput } from 'react-native'
function PhoneTextInput({
placeholder,
autoComplete,
autoFocus,
value,
onChange
}, ref) {
// Instead of `onChangeText` it could use `onChange` and get `value` from `nativeEvent.text`.
const onChangeText = useCallback((value) => {
onChange({
preventDefault() { this.defaultPrevented = true },
target: { value }
})
}, [onChange])
return (
<TextInput
ref={ref}
placeholder={placeholder}
autoFocus={autoFocus}
autoCompleteType={autoComplete}
keyboardType="phone-pad"
onChangeText={onChangeText}
value={value}/>
)
}
PhoneTextInput = React.forwardRef(PhoneTextInput)
PhoneTextInput.propTypes = {
placeholder: PropTypes.string,
autoComplete: PropTypes.string,
autoFocus: PropTypes.bool,
value: PropTypes.string,
onChange: PropTypes.func.isRequired
}
export default PhoneTextInput
Then, in a React Native application:
import React, { useState } from 'react'
import PhoneInput from 'react-phone-number-input/input'
import PhoneTextInput from './PhoneTextInput'
function Example() {
const [value, setValue] = useState()
return (
<PhoneInput
style={...}
smartCaret={false}
inputComponent={PhoneTextInput}
defaultCountry="US"
value={value}
onChange={setValue} />
)
}
Report in this issue if it works.
Also see the previous question: https://github.com/catamphetamine/react-phone-number-input/issues/283#issuecomment-552244455
@catamphetamine "without country select" doesn't work with react native. Although I am trying out a simple example with text input and the libphonenumber-js to work out something. Till now what I have done has worked till some extent but it will be great if you could help me in understanding how the smart caret works in your react component. For now the caret has a jumping effect when it meets with a blank space or a bracket.
@whimsicaldreamer
"without country select" doesn't work with react native.
How are you using it? Is it v3?
Till now what I have done has worked till some extent but it will be great if you could help me in understanding how the smart caret works in your react component. For now the caret has a jumping effect when it meets with a blank space or a bracket.
Smart caret is using input-format library.
@catamphetamine
How are you using it?
I am using it as per the instructions in the readme for using "without country select"
Is it v3?
Yes, the latest. 3.0.13.
Smart caret is using
input-formatlibrary.
Any suggestions on how to use with react native input or how you implement it with react input?
I am using it as per the instructions in the readme for using "without country select"
Then it won't work because React Native most likely doesn't support <select/>.
https://github.com/catamphetamine/react-phone-number-input/blob/master/source/PhoneInput.js
See if inputComponent={Select} fixes the issue.
Any suggestions on how to use with react native input or how you implement it with react input?
See the InputSmart.js file of this library if you want to copy the behavior.
Then it won't work because React Native most likely doesn't support
<select/>
Yes you are correct.
See if
inputComponent={Select}fixes the issue
You mean to pass in the react native TextInput component here?
You mean to pass in the react native TextInput component here?
Yes.
Maybe something like:
import React from 'react'
import { TextInput } from 'react-native'
export default function PhoneTextInput({
placeholder,
autoComplete,
autoFocus,
value,
onChange
}) {
return (
<TextInput
placeholder={placeholder}
autoFocus={autoFocus}
autoCompleteType={autoComplete}
keyboardType="phone-pad"
onChangeText={onChange}
value={value}
/>
);
}
Report if it works.
Ok, copying the above as a separate component and calling it as following:
<PhoneInput
country="IN"
inputComponent={ PhoneTextInput } // <= From your example component above
value={this.state.mobile_number}
onChange={ this._phoneInputHandler }
/>
Let me know if my interpretation is correct.
Yes, see if it works. I don't have React Native so I didn't check.
@catamphetamine On Load I get a warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
On typing in the first digit, I also get an error: TypeError: Undefined is not an object(evaluating 'input.value')
On Load I get a warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef().
The component uses React.forwardRef().
I added ref={...} on demo page to "without country select" and it didn't print any warning.
On typing in the first digit, I also get an error:
input.value is being accessed from input-format package.
input is the ref.
ref isn't working in your case for some reason, so input is undefined in input-format package.
Actually, we didn't forward ref in <PhoneTextInput/>.
See if this works:
import React from 'react'
import PropTypes from 'prop-types'
import { TextInput } from 'react-native'
function PhoneTextInput({
placeholder,
autoComplete,
autoFocus,
value,
onChange
}, ref) {
return (
<TextInput
ref={ref}
placeholder={placeholder}
autoFocus={autoFocus}
autoCompleteType={autoComplete}
keyboardType="phone-pad"
onChangeText={onChange}
value={value}
/>
)
}
PhoneTextInput = React.forwardRef(PhoneTextInput)
PhoneTextInput.propTypes = {
placeholder: PropTypes.string,
autoComplete: PropTypes.string,
autoFocus: PropTypes.bool,
value: PropTypes.string,
onChange: PropTypes.func.isRequired
}
export default PhoneTextInput
input.value is being accessed from input-format package.
Do I need to install the input-format package separately?? Since I still get the error: TypeError: Undefined is not an object(evaluating 'input.value'). Although the warning is gone.
Do I need to install the input-format package separately?
No, it's installed automatically.
The code above should work because it forwards ref now.
Did the forwardRef warning disappear?
Yes, the forward ref warning disappeared but I get the TypeError.
Doesn’t it show a stack trace?
On Thu, 23 Jan 2020 at 18:23, Ayan Dey [email protected] wrote:
Yes, the forward ref warning disappeared but I get the TypeError.
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/catamphetamine/react-phone-number-input/issues/296?email_source=notifications&email_token=AADUP3ZZJFBH2G4LJ3EFHGTQ7GZAXA5CNFSM4JMIZADKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJXXIII#issuecomment-577729569, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADUP33YW75QSG3MMW455OLQ7GZAXANCNFSM4JMIZADA .
I guess input-format is only for react.

So, the error originates at that function:
https://github.com/catamphetamine/input-format/blob/26abb77bec3ac5984f7fe99408846464fda6136a/source/input%20control.js#L35-L38
Called from here:
https://github.com/catamphetamine/input-format/blob/26abb77bec3ac5984f7fe99408846464fda6136a/source/react/Input.js#L35-L41
And input there is ref.current.
There, for some reason ref.current is undefined.
I read a bit about React Native, and found out that even if the input wasn't undefined, still there's no input.value property, so I guess input-format won't work in React Native.
The alternative then is passing smartCaret={false} property when creating a <PhoneInput/> "without country select" component element.
https://github.com/catamphetamine/react-phone-number-input/blob/d84e5ad751c60b083850a634899d9ad5e5039ce9/source/PhoneInput.js#L103
So, see if such code works:
import PhoneInput from 'react-phone-number-input/input`
<PhoneInput smartCaret={false} .../>
On adding smartCaret: { false } I receive a TypeError on keying in numbers.
This is what I have currently:
<PhoneInput
style={ styles.phoneNumberInput }
smartCaret={ false }
country="IN"
inputComponent={ PhoneTextInput }
value={ this.state.mobile_number }
onChange={ (number) => this._phoneInputHandler(number) }
/>

Oh, yes, change onChangeText to onChange in <PhoneTextInput/>.
On Fri, 24 Jan 2020 at 09:10, Ayan Dey [email protected] wrote:
On adding smartCaret: { false } I receive a TypeError.
[image: Screenshot_2020-01-24-11-38-40-638_com furry] https://user-images.githubusercontent.com/8104493/73048198-4c0e9380-3e9e-11ea-974a-45ba4b51a49e.jpg
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/catamphetamine/react-phone-number-input/issues/296?email_source=notifications&email_token=AADUP35VM5E462NIODWTGOTQ7KA5RA5CNFSM4JMIZADKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJZ2OUY#issuecomment-578004819, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADUP3ZMANUMVUAR77VMTKDQ7KA5RANCNFSM4JMIZADA .

So event.target.value is undefined at this line of code:
https://github.com/catamphetamine/react-phone-number-input/blob/d84e5ad751c60b083850a634899d9ad5e5039ce9/source/InputBasic.js#L26
You can add some kind of console.log(event.target.value) in onChange to see what's the value there.
<PhoneTextInput onChange={event => { console.log(event); onChange(event); }}/>
The log turns out to be huge! So I am pasting the nativeEvent right after I typed a single digit 9:
"nativeEvent": {"eventCount": 1, "target": 43, "text": "9"}, "target": 43, "timeStamp": 1579864644085, "type": undefined}
Huh, so target is a number in React Native?
How does one get value then.
Well, ok, then try this instead:
<PhoneTextInput onTextChange={value => onChange({
preventDefault() { this.defaultPrevented = true },
target: { value }
})}/>
It creates an event stub from a value.
Perhaps there're more correct ways.
I guess we get the values from nativeEvent.text.
<PhoneTextInput onTextChange={value => onChange({ preventDefault() { this.defaultPrevented = true }, target: { value } })}/>
Where should I try the above?
@whimsicaldreamer
I guess we get the values from
nativeEvent.text.
Maybe. That could be a second route. Not yet though.
Where should I try the above?
I meant:
<TextInput onTextChange={(value) => onChange({
preventDefault() { this.defaultPrevented = true },
target: { value }
})}/>
My current implementation was as following:
<PhoneInput
style={ styles.phoneNumberInput }
smartCaret={ false }
country="IN"
inputComponent={ PhoneTextInput }
value={ this.state.mobile_number }
onChange={ (number) => this._phoneInputHandler(number) }
/>
where PhoneTextInput is:
function PhoneTextInput({
placeholder,
autoComplete,
autoFocus,
value,
onChange,
style,
}, ref) {
return (
<TextInput
style={ style }
ref={ ref }
placeholder={ placeholder }
autoFocus={ autoFocus }
autoCompleteType={ autoComplete }
keyboardType="phone-pad"
onChange={ event => { console.log(event); onChange(event); } }
value={ value }
onTextChange={value => onChange({
preventDefault() {
this.defaultPrevented = true
},
target: {value}
})}
/>
);
}
PhonePadInput = React.forwardRef(PhoneTextInput);
I am not sure if this is the way you mean.
On a side note, I have been trying out to implement this on my own without react-phone-number-input library and using only libphonenumber-js. I have been able to get the formatting done on the fly but one issue arises and that is on erasing a phone number entered. The issue is similar to this: https://github.com/catamphetamine/libphonenumber-js/issues/225. If you would like to know how I am doing it, I would love to paste it in here.
Remove onChange={ event => { console.log(event); onChange(event); } } because it's now replaced with onChangeText.
If you would like to know how I am doing it, I would love to paste it in here.
I won't assist with any custom components, only with parts of react-phone-number-input.