移动到maxlength react功能组件后的下一个输入



我使用react-Hook-form,我有一个电话号码的场景,它有三个输入字段XXX-XXX-XXXX。我想在到达maxlength== 3后将焦点从第一个输入转移到下一个输入。请建议在达到最大长度后自动对焦下一个电话输入的解决方案。正在开发react功能组件

下面是代码,

import React from 'react';
import { useForm } from "react-hook-form";
export function PhoneInput(props) {
const {
register,
handleSubmit,
watch,
clearErrors,
formState: { errors }
} = useForm();
return (
<form className="review-your-info-form" id="purchase-form" onSubmit={handleSubmit(onSubmit)} noValidate>
<div className="field">
{ (errors.phone1 || errors.phone2 || errors.phone3)  && <div className="error-msg"><span className="required">{errors.phone1?.message || errors.phone2?.message || errors.phone3?.message}</span></div>}
<label htmlFor="phone1">Phone *</label>
<div className="phone-group flex">
<input
id="phone1"
type="tel"
className="phone1"
maxLength="3"
onClick={() => clearErrors("phone1")}
{...register("phone1",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
type="tel"
className="phone2"
maxLength="3"
onClick={() => clearErrors("phone2")} 
{...register("phone2",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
type="tel"
className="phone3"
maxLength="4"
onClick={() => clearErrors("phone3")} 
{...register("phone3",{
required: 'phone-error',
minLength: {
value: 4,
message: 'phone-error'
},
pattern: {
value: /^[0-9]*$/i,
message: 'phone-error'
},
})}
/>
</div>
</div>
</form>
)}```

要在React中移动焦点,可以使用useRefhook:

import React, { useState, useRef } from 'react';
import { useForm } from "react-hook-form";
export function PhoneInput(props) {
const [input, setInput] = useState();
const {
register,
handleSubmit,
watch,
clearErrors,
formState: { errors }
} = useForm();
const inputToFocus = useRef(); //<-- create ref
const handleChange = (e) => {
setInput(e.target.value);
if (e.target.value.length >= 3) inputToFocus.current.focus(); //<--- focus second input
}
return (
<form className="review-your-info-form" id="purchase-form" onSubmit={handleSubmit(onSubmit)} noValidate>
<div className="field">
{ (errors.phone1 || errors.phone2 || errors.phone3)  && <div className="error-msg"><span className="required">{errors.phone1?.message || errors.phone2?.message || errors.phone3?.message}</span></div>}
<label htmlFor="phone1">Phone *</label>
<div className="phone-group flex">
<input
value={input}
onChange={handleChange} //<-- edit input
id="phone1"
type="tel"
className="phone1"
maxLength="3"
onClick={() => clearErrors("phone1")}
{...register("phone1",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
ref={inputToFocus}  //<-- assing ref
type="tel"
className="phone2"
maxLength="3"
onClick={() => clearErrors("phone2")} 
{...register("phone2",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
type="tel"
className="phone3"
maxLength="4"
onClick={() => clearErrors("phone3")} 
{...register("phone3",{
required: 'phone-error',
minLength: {
value: 4,
message: 'phone-error'
},
pattern: {
value: /^[0-9]*$/i,
message: 'phone-error'
},
})}
/>
</div>
</div>
</form>
)}

解释:当值达到长度为3时,第一次输入必须将焦点传递给第二次输入,所以:

  1. 我创建一个inputToFocusref并分配给第二个输入;
  2. 然后我创建handleChange函数:设置第一个输入值,如果值长度>= 3,使用先前创建的ref将焦点移动到第二个输入。

对于一个更新的答案:我有同样的问题,我用React Hook Form API使用Watch和setFocus修复了它,所以你观察所有的输入,如果它们改变,然后你"跳转";使用setFocus切换到下一个输入。这样就不需要依赖useRef:

import React, { useEffect } from 'react';
import { useForm } from "react-hook-form";
export function PhoneInput(props) {
const {
register,
handleSubmit,
watch,
setFocus,
clearErrors,
formState: { errors }
} = useForm();
const watchAllInputs = watch() // With this you watch all inputs when change


useEffect(() => watchAllInputs.hasOwnProperty("phone1") && (watchAllInputs.phone1.length > 3 && setFocus("phone2")), [watchAllInputs]  )

return (
<form className="review-your-info-form" id="purchase-form" onSubmit={handleSubmit(onSubmit)} noValidate>
<div className="field">
{ (errors.phone1 || errors.phone2 || errors.phone3)  && <div className="error-msg"><span className="required">{errors.phone1?.message || errors.phone2?.message || errors.phone3?.message}</span></div>}
<label htmlFor="phone1">Phone *</label>
<div className="phone-group flex">
<input
id="phone1"
type="tel"
className="phone1"
maxLength="3"
onClick={() => clearErrors("phone1")}
{...register("phone1",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
type="tel"
className="phone2"
maxLength="3"
onClick={() => clearErrors("phone2")} 
{...register("phone2",{
required: 'phone-error',
minLength: {
value: 3,
message: 'phone-error'
},
pattern: {
value: /[2-9][0-9]{2}$/,
message: 'phone-error'
},
})}
/>
<input
type="tel"
className="phone3"
maxLength="4"
onClick={() => clearErrors("phone3")} 
{...register("phone3",{
required: 'phone-error',
minLength: {
value: 4,
message: 'phone-error'
},
pattern: {
value: /^[0-9]*$/i,
message: 'phone-error'
},
})}
/>
</div>
</div>
</form>
)}

最新更新