react-input-mask与react-hook-form的setValue配合失效问题求助
react-hook-form setValue 无法给 react-input-mask 组件赋值
问题描述
我通过useEffect从API获取数据,并用react-hook-form的setValue给表单赋值,name和email字段正常,但phone字段始终为空。
获取数据的useEffect代码:
useEffect(() => { const getData = async () => { const response = await api.get(`/clientes/${id}`) if (response.status === 200) { setValue('name', response.data.name) setValue('email', response.data.email) console.log(response.data.phone) // (51) 99999-9999 setValue('phone', response.data.phone) } } getData() }, [id, setValue])
InputMask组件代码:
<label> Telefone <InputMask mask="(99) 99999-9999" maskChar="_" type="text" id="celular" {...register('celular')} /> {errors.celular && ( <EditClientFormError> {errors.celular.message} </EditClientFormError> )} </label>
我尝试把手机号转为纯数字再赋值,依然无效:
useEffect(() => { const getData = async () => { const response = await api.get(`/clientes/${id}`) if (response.status === 200) { setValue('name', response.data.name) setValue('email', response.data.email) const numberWithoutMask = response.data.phone.replace(/\D/g, '') const number = parseInt(numberWithoutMask, 10) console.log(number) // 51999999999 setValue('phone', number) } } getData() }, [id, setValue])
推测问题出在InputMask组件,求解决方法。
解决方案
1. 修正字段名不匹配问题
最核心的错误是字段名不一致:你在setValue中使用的是phone,但InputMask组件通过register注册的字段是celular,两者完全不对应,导致赋值无法生效。
直接把setValue('phone', ...)改为setValue('celular', ...)。
2. 适配InputMask的赋值格式
react-input-mask要求赋值内容为纯数字字符串(不要转成Number类型),这样组件才能正确应用掩码格式。修改后的useEffect代码:
useEffect(() => { const getData = async () => { const response = await api.get(`/clientes/${id}`) if (response.status === 200) { setValue('name', response.data.name) setValue('email', response.data.email) // 提取纯数字字符串,保留字符串类型 const purePhoneStr = response.data.phone.replace(/\D/g, '') // 给正确的字段赋值 setValue('celular', purePhoneStr) } } getData() }, [id, setValue])
3. 用Controller组件增强绑定可靠性
如果上述方法仍有问题,推荐使用react-hook-form的Controller组件包裹InputMask,它能更好地处理受控组件的状态同步:
import { Controller } from "react-hook-form"; // 替换原InputMask代码 <label> Telefone <Controller name="celular" control={control} // 从useForm中解构出的control对象 render={({ field }) => ( <InputMask mask="(99) 99999-9999" maskChar="_" type="text" id="celular" {...field} /> )} /> {errors.celular && ( <EditClientFormError> {errors.celular.message} </EditClientFormError> )} </label>
使用Controller后,setValue('celular', purePhoneStr)依然可以正常赋值,同时能避免受控/非受控组件的状态冲突问题。
内容的提问来源于stack exchange,提问作者Pedro Schinke
相关产品推荐
相关产品推荐

