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