如何将react-intl-tel-input与formik集成?

时间:2019-01-31 12:57:22

标签: reactjs formik intl-tel-input

我正在使用Formik处理我的ReactJs应用程序中的表单,我想使用react-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>}

哪个是实现此目的的正确方法?我的意思是使用自定义组件,但能够使用Formik的handleChange,handleBlur和验证架构?

预先感谢...

2 个答案:

答案 0 :(得分:0)

这不是最佳解决方案,但会将IntlTelInput链接回formik的setFieldTouched和setFieldValue。

// @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]);
};

使用诸如validate.js之类的验证器来检查电话号码是否不是“ invalid_phone_number”

.

答案 1 :(得分:0)

如果有人希望将其集成到功能组件(而不是基于类的组件)中,则可以节省一些时间! :)

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import IntlTelInput from 'react-intl-tel-input';
import { Field } from 'formik';
import 'react-intl-tel-input/dist/main.css';

const TelephoneInput = ({ name, ...props }) => {

  const [telephoneValid, setTelephoneValid] = useState(true);
  const setValidity = valid => {
    setTelephoneValid(valid);
  };
  // process number into string with area code for submission
  const processNumber = (isValid, phone, country) => {
    return `+${country.dialCode} ${phone}`;
  };

  return (
    <>
      <Field name={name}>
        {(
          { field: { value },
          form: { isSubmitting, setFieldTouched, setFieldValue } }) =>
            <IntlTelInput
              {...props}
              containerClassName="intl-tel-input"
              inputClassName={telephoneValid ? 'valid' : 'invalid'}
              label="telephone"
              defaultValue={value}
              disabled={isSubmitting}
              fieldId={name}
              fieldName={name}
              onPhoneNumberBlur={(isValid) => {
                setFieldTouched(name, true);
                setValidity(isValid);
              }}
              onPhoneNumberChange={(isValid, phone, country) => {
                setFieldValue(name, processNumber(isValid, phone, country));
              }}
            />
        }
      </Field>
    </>
  );
};

TelephoneInput.propTypes = {
  name: PropTypes.string.isRequired,
};
export default TelephoneInput;