Как интегрировать response-intl-tel-input с formik? - PullRequest
0 голосов
/ 31 января 2019

Я использую Formik для обработки форм в своем приложении ReactJs, я хотел бы использовать response-intl-tel-input для обработки телефонного номера, однако я не могу интегрировать handleChange, handleBlur и проверки с Formik.Прямо сейчас я использую состояние моей формы, чтобы сохранить номер телефона и его статус проверки, но это создает проблему с Formik путем повторного рендеринга моих других полей.

Вот мой компонент номера телефона:

<IntlTelInput
  fieldId="userPhoneNumber"
  fieldName="userPhoneNumber"
  value={values.userPhoneNumber}
  preferredCountries={preferredMobileCountries}
  css={['intl-tel-input', `form-control ${(!validPhoneNumber) ? 'is-invalid' : ''}`]}
  style={{display: 'block',width: '100%'}}
  format
  onPhoneNumberChange={this.handlePhoneChange}
/>
{!validPhoneNumber && <div className="invalid-feedback">Invalid phone number</div>}

Как правильно это сделать?Я имею в виду использовать пользовательский компонент, но иметь возможность использовать handleChange, handleBlur и схему проверки Formik?

Заранее спасибо ...

1 Ответ

0 голосов
/ 14 февраля 2019

Это не оптимальное решение, но связывает обратно IntlTelInput с setFieldTouched и setFieldValue от formik.

// @flow

import React, {Component, Fragment} from 'react';
import {ErrorMessage, Field} from 'formik';
import IntlTelInput from 'react-intl-tel-input';

export default class MobileField extends Component {
  formatPhoneNumberOutput(
    isValid: boolean,
    newNumber: string,
    countryData: Object,
    fullNumber: string,
    isExtension: boolean
  ) {
    if (isValid && fullNumber) {
      return fullNumber.replace(/(\s|-)/g, '');
    }
    return 'invalid_phone_number'; // caught by validator
  }

  render() {
    return (
      <Field
        name={name}
        render={({field, form: {errors, isSubmitting, touched, setFieldTouched, setFieldValue}}) => {
          return (
            <Fragment>
              <IntlTelInput
                defaultCountry="fr"
                defaultValue={field.value}
                disabled={isSubmitting}
                fieldId={name}
                fieldName={name}
                onPhoneNumberBlur={() => {
                  setFieldTouched(name, true);
                }}
                onPhoneNumberChange={(...args) => {
                  setFieldValue(name, this.formatPhoneNumberOutput(...args));
                }}
                preferredCountries={['fr', 'gb', 'es', 'be', 'de']}
              />
              <ErrorMessage name={name} render={msg => <p>{msg}</p>} />
            </Fragment>
          );
        }}
      />
    );
  }
}

использует валидатор, например validate.js, чтобы проверить, что номер телефона не является "invalid_phone_number"

// @flow

import _mapValues from 'lodash/mapValues';
import validate from 'validate.js';

export type Values = {
    mobile: string,
    landline: string
};

export default (values: Values) => {
    const options = {
        fullMessages: false
    };
  const validation: {[key: string]: string[]} = validate(
      values,
      {
          mobile: {
              presence: {message: 'Please add a mobile phone number'},
              format: {
                  pattern: '^((?!invalid_phone_number).)*$', // is not invalid_phone_number
                  message: 'This phone number looks like being invalid'
              }
        },
        landline: {}
    },
    options
    );
    return _mapValues(validation, messages => messages[0]);
};
...