React Formik Mui TextField with custom input loosing focus

Viewed 478

I have a Formik form which contains a few Material UI TextField components. All of them works fine, except for one who looses focus when onChange() is executed. It has a PhoneInput (react-phone-number-input) component as a custom input. Everything works fine (data is being saved, etc.), but I have to keep clicking on the input to continue writing on it.

I have a feeling it has something to do with the ref. When logging inputRef (PhoneInputRef, provided by TextField) it doesn't look like a normal ref.

Formik component (Parent)

{...}
<Formik
  initialValues={initialValues}
  validationSchema={validationSchema}
  onSubmit={handleClickRegister}>
  {(props) => <RegisterForm {...props} />}
</Formik>
{...}

Form (Children)

{...}

const {
    values: {
        firstName,
        lastName,
        email,
        confirmEmail,
        password,
        confirmPassword,
        phoneNumber,
    },
//Formik methods passed as props
    errors,
    touched,
    handleChange,
    handleSubmit,
    setFieldValue,
    setFieldTouched,
} = props;

{...}

//Formik onChange handler (used by every TextField besides the one containing PhoneInput)
const change = (name, e) => {
  e.persist();
  handleChange(e);
  setFieldTouched(name, true, false);
};

//Custom onChange handler for Formik (used by PhoneInput)
const handleOnChange = (name, value) => {
  setFieldValue(name, value);
  setFieldTouched(name, true, false);
};

{...}

{/*NORMAL TEXTFIELD*/}

<TextField
  className={classes.inputField}
  id="confirmPassword"
  name="confirmPassword"
  label={t("header.registerDialog.form.labelConfirmPassword")}
  value={confirmPassword}
  onChange={change.bind(null, "confirmPassword")}
  error={touched.confirmPassword && Boolean(errors.confirmPassword)}
  helperText={
    touched.confirmPassword && errors.confirmPassword ? (
      errors.confirmPassword
    ) : (
      <>
        &nbsp;
        <br />
      </>
    )
  }
/>

{/*CUSTOM INPUT TEXTFIELD*/}

<TextField
  className={classes.textFieldPhoneInput}
  key="textFieldPhone"
  ref={textFieldRef}
  id="phoneNumber"
  name="phoneNumber"
  label={t("header.registerDialog.form.labelPhone")}
  InputLabelProps={{
    className: phoneNumber
      ? classes.inputFieldPhoneLabel
      : classes.inputFieldPhoneLabelEmpty,
  }}
    InputProps={{
      inputComponent: ({ inputRef, ...rest }) => (
        <PhoneInput
          {...rest}
          key="phoneInput"
          ref={inputRef}
          international
          countryCallingCodeEditable={false}
          name="phoneNumber"
          defaultCountry="AR"
          onChange={(phone) =>
            handleOnChange("phoneNumber", phone)
          }
          labels={phoneLanguage}
          value={phoneNumber}
        />
      ),
    }}
    error={touched.phoneNumber && Boolean(errors.phoneNumber)}
    helperText={
      touched.phoneNumber && errors.phoneNumber ? (
        errors.phoneNumber
      ) : (
        <>
          &nbsp;
          <br />
        </>
      )
    }
/>

{...}

0 Answers
Related