bl00mber / react-phone-input-2

:telephone_receiver: Highly customizable phone input component with auto formatting
https://bl00mber.github.io/react-phone-input-2.html
MIT License
949 stars 536 forks source link

Issue with Canada/USA, Russia/Kazakhstan, countries with same calling code #377

Open ghost opened 3 years ago

ghost commented 3 years ago

Hi, If from the dropdown we select Canada which has the same calling code as the USA. The component will show USA flag. Same for other countries with the same callin code.

Here is a link for sandbox: https://codesandbox.io/s/boring-lake-fe5o5?file=/src/App.js

Manimall commented 3 years ago

https://github.com/bl00mber/react-phone-input-2/issues/398

Manimall commented 3 years ago

Hi, If from the dropdown we select Canada which has the same calling code as the USA. The component will show USA flag. Same for other countries with the same callin code.

Here is a link for sandbox: https://codesandbox.io/s/boring-lake-fe5o5?file=/src/App.js

definitely, it's a huge bug

Manimall commented 3 years ago

i found i kinda-of solution there, it's not pretty, but in the end - it works)

We can use fourth argument in onChange fn - and create a wrapper component to avoid this problem -

const PhoneInputWrapper: FC<PhoneInputWrapperProps > = ({
  value,
  onChange,
  ...props
}) => {
  const [phoneValue, setPhoneValue] = useState(value);

  const handlePhoneChange = useCallback(
    (
      value: string,
      _data: Record<string, never>,
      _e: ChangeEvent<HTMLInputElement>,
      formattedValue: string,
    ) => {
      // saving and sending unformatted value to backend
      onChange(value);

      // changing the component state correctly
      setPhoneValue(formattedValue);
    }, []);

  return (
    <PhoneInput
      { ...props }
      value={phoneValue}
      onChange={handlePhoneChange} />
  );
};

export default PhoneInputWrapper;
Anton-SN commented 2 years ago

I found a similar problem and its solution https://github.com/bl00mber/react-phone-input-2/issues/221

dev-mani7 commented 2 years ago

any buddy got solution for this issue?

TheEagleGame commented 1 year ago

I add this areaCodes={{ kz: [7, 6] }} and now it works fine for Kazahstan +76...., +77... - now it Kazahstan (not Russia)

hafidFrn commented 1 year ago

just add disableCountryGuess= {true}

valentynay06 commented 1 year ago

In input, we display only 2 country have a problem when enter Canada number, after component re-render country change to the USA.

abhilashathampi15 commented 1 month ago

I was also faced the same issue and the following fix resolved it

Ensure the phone number is displayed correctly by managing the value state separately and preventing unnecessary re-renders when the country changes.

import React, { FocusEvent, useEffect, useState } from 'react' import PhoneInput from 'react-phone-input-2' import { useAppSelector } from '../../_helpers/hooks' import './phoneInput.scss'

interface ICountryData { countryCode: string dialCode: string format: string name: string }

interface IPhoneField { name: string value: string | undefined isValid?: boolean disabled?: boolean onBlur: (e: FocusEvent) => void onChange: ( value: string, data: Record<string, never> | ICountryData, event: React.ChangeEvent, formattedValue: string, ) => void }

interface IPhoneNumberInput { phoneField: IPhoneField style: React.CSSProperties isMandatory: boolean isoCode?: string }

const PhoneNumberInput = ({ phoneField, style, isMandatory, isoCode }: IPhoneNumberInput) => { const translatedInput = useAppSelector((state) => state?.translation.translatedData) const [internalValue, setInternalValue] = useState<string | undefined>(phoneField.value) useEffect(() => { setInternalValue(phoneField.value) // eslint-disable-next-line react-hooks/exhaustive-deps }, [phoneField.value])

const handleChange = ( value: string, data: ICountryData, event: React.ChangeEvent, ) => { setInternalValue(value) phoneField.onChange(value, data, event, value) }

return ( <PhoneInput {...phoneField} value={internalValue} country={isoCode?.toLowerCase() || 'us'} placeholder={translatedInput?.common?.phoneLabel} specialLabel={${translatedInput?.common?.phoneLabel}${isMandatory ? '*' : ''}} defaultErrorMessage={translatedInput?.common?.defaultPhoneError} inputStyle={style} inputProps={{ required: true, autoFocus: false, }} disabled={phoneField.disabled} disableCountryGuess countryCodeEditable={false} onChange={handleChange} /> ) }

export default PhoneNumberInput

This approach should ensure that both the flag and the phone number are displayed correctly and remain synchronized.