react-native-phone-number-input icon indicating copy to clipboard operation
react-native-phone-number-input copied to clipboard

Country flag and code does not get updated upon load

Open ashton-hoss opened this issue 4 years ago • 10 comments

Once again thanks for the library. I was testing this on my app and realized when I go the page which has this component in, when the number is loaded, the country flag does not get load correctly (in an event that state gets changed).

Is there any work around this? Maybe a prop similar to defaultValue and value? or a function cuch as setCounty()

ashton-hoss avatar Jan 09 '21 23:01 ashton-hoss

Have you found any workaround? Facing the same issue

sengchunyee avatar Jan 20 '21 11:01 sengchunyee

async componentDidMount() { const { defaultCode } = this.props; if (defaultCode) { const code = await getCallingCode(defaultCode); this.setState({ code }); } }

this seems to be the issue

kosalamoon avatar Feb 03 '21 15:02 kosalamoon

Same here. If you set the default value with a different calling code. And then try to extract the calling/country code. It always extract the default

jcisz avatar Feb 11 '21 17:02 jcisz

  1. const [ ready, setReady ] = useState(false);
  2. Return null if state ready = false;
  3. Make changes in state for country code and setReady(true);

theRealSheng avatar Feb 23 '21 14:02 theRealSheng

@theRealSheng can you provide example please

saadelsabahy avatar Apr 13 '21 13:04 saadelsabahy

@saadelsabahy ` import React, { useState, useRef, useEffect } from 'react'; import PropTypes from 'prop-types'; import I18n from 'react-native-i18n'; import _ from 'lodash'; import { View, Text } from 'react-native'; import PhoneInput from 'react-native-phone-number-input'; import parsePhoneNumberFromString from 'libphonenumber-js'; import maxList from 'libphonenumber-js/metadata.full.json';

import styles from './styles';

import { DynamicFormContextAPIShape } from '../../../../Context/DynamicFormContext';

const PhoneComponent = ({ api, configuration, data, }) => { const [ ready, setReady ] = useState(false); const [ value, setValue ] = useState(''); const [ countryCode, setCountryCode ] = useState(null); const [ formattedValue, setFormattedValue ] = useState(''); const [ valid, setValid ] = useState(true); const phoneInput = useRef(null);

useEffect(() => {

const findCountryCode = (countryCallingCode, metadata) => {
  if (countryCallingCode === '1'){
    return 'US';
  }

  let countryCode;

  for(let i=0; i < Object.keys(metadata.countries).length; i++) {
    if (metadata.countries[i][0] === countryCallingCode) {
      countryCode = metadata.countries[i];
      break;
    }
  }
  
  return countryCode;
}

const setInitialValues = async () => {
  const { value } = data;

  if (value) {
    const data = parsePhoneNumberFromString(`+${value}`);
    if (data) {
      const { 
        country,
        countryCallingCode,
        nationalNumber,
        number,
        metadata
      } = data;
      const countryCode = country ? country : findCountryCode(countryCallingCode, metadata);

      setCountryCode(countryCode)
      setValue(nationalNumber)
      setFormattedValue(number);
    }
  } else {
    setCountryCode('US')
  }
  setReady(true)
}

setInitialValues();

}, [data])

const onChange = (text) => { const number = String(text).replace(/\D+/g, ''); setValue(number); if (!valid) { setValid(true); } };

const onChangeFormattedText = (text) => { const number = String(text).replace(/\D+/g, ''); setFormattedValue(+${number}); const { section, id } = configuration; api.onFieldValueChange(section, id, number) };

const onFinish = () => { const { section, id } = configuration; api.onFieldValueChange(section, id, formattedValue.replace('+', '')) }

if (!ready) { return null; }

let maxLength = 0;

if (maxList.countries[countryCode]) { maxLength = maxList.countries[countryCode][3][0] }

return ( <View style={styles.container}> <PhoneInput ref={phoneInput} value={value} defaultCode={countryCode} defaultValue={value} layout='first' onChangeText={onChange} onChangeFormattedText={onChangeFormattedText} containerStyle={styles.input} textInputStyle={styles.input} textInputProps={{ onBlur: onFinish, keyboardType: 'phone-pad', maxLength }} withAlphaFilter={false} /> {!valid && ( <Text style={styles.noValid}> {I18n.t('number_not_valid')} </Text> )} </View> ); };

PhoneComponent.propTypes = { configuration: PropTypes.object.isRequired, data: PropTypes.object.isRequired, api: DynamicFormContextAPIShape }

export default PhoneComponent

`

theRealSheng avatar Apr 13 '21 20:04 theRealSheng

Hey. Your example is not correct. When updated country code state in componentDidMount() => doesn't update render as changed country code. This means initial country code state value is 'US', fetched country code is 'DE' in componentDidMount() => country code is still 'US'. Is this correct and useful component? This is correct only when update state in componentWillMount().

XiaoLong9012 avatar May 23 '21 14:05 XiaoLong9012

Same issue here. It doesn't update when I fetch number from api on componentDidMount(initial useEffect). Any solutions?

webdevsmart avatar Jun 11 '22 03:06 webdevsmart

You can refer to #85

baronchng avatar Aug 06 '22 18:08 baronchng

any work around?

Standin-Alone avatar Nov 25 '22 12:11 Standin-Alone