Next.js与react-hook-form集成时Ref无法正常工作问题求助
解决Next.js + TypeScript中react-hook-form的类型与运行时错误
我前阵子刚踩过这个坑!你遇到的问题其实是react-hook-form v7版本的API重大变更导致的——你用的是v6及以前的旧写法,但v7里register的用法完全不一样了,这直接引发了类型错误和运行时的path.split报错。
错误原因拆解
- 类型错误:v7里的
register是一个需要传入字段名的函数,而不是直接可以赋值给ref的对象/回调。IDE提示的类型不兼容,就是因为你把UseFormRegister类型的函数直接传给了需要LegacyRef<HTMLInputElement>的ref属性。 - 运行时错误:当React把input的DOM实例传给
ref(也就是你传的register函数)时,register期望接收的是字段名字符串,结果拿到了DOM对象,自然会在调用split方法时报错——因为DOM对象没有split方法。
快速修复方案
只需要把ref={register}改成调用register('字段名')并展开返回的属性就行,同时给useForm加上TypeScript泛型来获得类型提示:
import { useForm } from 'react-hook-form'; // 定义表单字段的类型,替换any获得类型安全 interface FormInputs { name: string; } const Component = () => { // 给useForm指定泛型,绑定表单字段类型 const { register, handleSubmit } = useForm<FormInputs>(); // onSubmit的data现在会有正确的类型提示,不用any了 const onSubmit = (data: FormInputs) => { console.log(data); }; return ( <form noValidate onSubmit={handleSubmit(onSubmit)}> {/* 用扩展运算符把register返回的ref、name等属性都传给input */} <input type="text" id="name" {...register('name')} /> <button type="submit">提交</button> </form> ); }; export default Component;
额外说明
如果你不想用扩展运算符,也可以手动解构register返回的属性:
const { ref, name, onChange, onBlur } = register('name'); <input type="text" id="name" ref={ref} name={name} onChange={onChange} onBlur={onBlur} />
不过扩展运算符的写法更简洁,推荐使用。
这样修改后,IDE的类型错误会自动消失,运行时的path.split报错也会解决——本质上就是按照v7的正确API使用register函数。
内容的提问来源于stack exchange,提问作者Damian Kociszewski
相关产品推荐
相关产品推荐

