尝试将 react-hook-form 与 react-input 掩码结合使用

Trying to use react-hook-form in combination with react-input mask

我有以下设置。我的面具会出现,但是当我输入它时它只是跳到行尾我不太确定我在这里做错了什么。我已经尝试将所有道具放在父组件中并通过传播将它们全部传递,但那没有用。如果有人能告诉我先调试哪里,我会提供更多调试。

提前致谢

import React from "react"
import { useForm } from "react-hook-form"
import MaskedInput from "react-input-mask"

const Quote = () => {
  const { register, handleSubmit, watch, errors } = useForm();
  const [tel, setTel] = React.useState("");

  render(
    <MaskedInput
      mask="(780) 000-0000"
      alwaysShowMask
      onChange={(e) => setTel(e.target.value)}
      value={tel}
      name={data.title}
    >
      {(inputProps) => (
        <input
          ref={register({
            required: true,
            pattern: /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im,
          })}
          value={inputProps.tel}
          name={inputProps.name}
          {...inputProps}
        />
      )}
    </MaskedInput>
  );
};

掩码格式错误需要这样

mask="(+7 (999) 999-99-99)"

帮助别人

如果您使用不受控制的输入字段(如本机输入),您可以使用函数来屏蔽输入

这不能与受控输入字段一起使用,例如 (Material UI)

示例@component/input.tsx

import React from 'react'
import { Container, ErrorMessage } from './styles'

interface InputProps {
  label?: string | true
  defaultValue?: string
  name?: string
  type?: string
  mask?: (value: string) => string
  placeholder?: string
  disabled?: boolean
  error?: any
  value?: string
  register?: any
}
const Input: React.FC<InputProps> = ({
  label,
  defaultValue,
  name,
  type,
  mask = (value: string) => value,
  value,
  placeholder,
  disabled,
  error,
  register,
  ...inputProps
}) => {
  return (
    <Container>
      {label && (
        <label htmlFor={name}>
          {(typeof label === 'string' && label) ||
            placeholder ||
            'Preencha este campo'}
        </label>
      )}
      <input
        onChange={e => (e.target.value = `${mask(e.target.value)}`)}
        disabled={disabled}
        ref={register}
        id={name}
        name={name}
        type={type}
        value={value}
        placeholder={placeholder}
        defaultValue={defaultValue}
        {...inputProps}
      />
      {error && <ErrorMessage>{error.message}</ErrorMessage>}
    </Container>
  )
}

export default Input

用法示例@page/form.tsx

function CPFMask(v: string): string {
  v = v.replace(/\D/g, '')
  v = v.replace(/^(\d{3})(\d)/g, '.')
  v = v.replace(/^(\d{3})\.(\d{3})(\d)/, '..')
  v = v.replace(/^(\d{3})\.(\d{3})\.(\d{3})(\d)/, '..-')
  v = v.replace(/^(\d{3})\.(\d{3})\.(\d{3})\/(\d{2})(\d)/, '..-')
  return v.substring(0, 14)
}

...

<Input
      type="text"
      mask={CPFMask}
      placeholder="CPF"
      name="cpf"
      label
      register={register({
        required: {
          value: true,
          message: 'CPF é obrigatório',
        },
        pattern: {
          value: /([0-9]{2}[\.]?[0-9]{3}[\.]?[0-9]{3}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}[\.]?[0-9]{3}[\.]?[0-9]{3}[-]?[0-9]{2})/i,
          message: 'CPF inválido',
        },
      })}
      error={errors.cpf}
    />
...

举个例子,用一个函数包裹children,让我们把InputMask当作Controller,把children当作render。所以我将 ref 属性放在 children 上,将 ref 错误直接重定向到 children 或渲染,而不是控制器。

<InputMask name="npwp" mask="99.999.999.9-999.999">
  {(inputProps) => (
    <input
      {...inputProps}
      ref={register}
      type="text"
      placeholder="Input NPWP"
    />
  )}
</InputMask>

对于那些使用 react-hook-form 版本 7 的人,这里有一个如何让它工作的例子:

    <Controller
      name="your input name"
      control={control}
      defaultValue=""
      rules={{
        required: true,
      }}
      render={({ field }) => (
        <MaskedInput
          mask="99/99"
          maskChar=""
          value={field.value}
          onChange={field.onChange}
        >
          {(inputProps: any) => (
            <input
              {...inputProps}
              type="text"
            />
          )}
        </MaskedInput>
      )}
    />