React+TS中React Hook Form向自定义Input组件传值报错如何解决?
报错原因
- 原生
<input>标签不存在register属性,你直接将react-hook-form的register函数作为prop传给原生input,触发了类型校验报错。 register是高阶函数,需要调用并传入表单项name属性,返回的包含onChange/onBlur/ref/name的对象才是符合原生input属性要求的绑定值。- 类型定义不匹配导致的props缺失提示,是因为register的泛型和表单数据类型没有对齐。
修复代码
1. Input.tsx 核心修改
import { UseFormRegister, FieldValues } from 'react-hook-form'; interface Props { label: string; className?: string; name: string; type: string; required: boolean; register: UseFormRegister<FieldValues>; } const Input: React.FC<Props> = ({ label, className = '', name, type, required, register }) => { return ( <fieldset className='form-fieldset'> <label htmlFor={name} className='label'> {label} {/* 核心修改:调用register传入name和校验规则,展开返回的属性绑定到input */} <input type={type} className={className} id={name} {...register(name, { required: required })} /> </label> </fieldset> ); }; export default Input;
2. 可选:泛型改造获得更安全的类型提示(推荐)
如果需要适配不同表单的类型校验,可以将Input改为泛型组件,不需要修改Form.tsx的代码即可自动对齐表单类型:
import { UseFormRegister, FieldValues, RegisterOptions } from 'react-hook-form'; interface Props<T extends FieldValues> { label: string; className?: string; name: keyof T; type: string; required?: boolean; register: UseFormRegister<T>; rules?: RegisterOptions<T>; } const Input = <T extends FieldValues>({ label, className = '', name, type, required = false, register, rules = {} }: Props<T>) => { return ( <fieldset className='form-fieldset'> <label htmlFor={name as string} className='label'> {label} <input type={type} className={className} id={name as string} {...register(name, { required, ...rules })} /> </label> </fieldset> ); }; export default Input;
额外说明
Form.tsx的代码不需要做任何修改,修改完Input组件后两个报错都会消失,表单数据绑定也会恢复正常。
内容的提问来源于stack exchange,提问作者CIB
相关产品推荐
相关产品推荐

