使用react-hook-form的Controller组件时触发无效Hook调用错误
React Hook Form Controller 数字输入触发 Invalid Hook Call 错误的解决办法
作为react-hook-form新手,我原本想让Controller组件处理数字类型的输入值,参考相关方案修改代码后,却触发了Invalid Hook Call错误,以下是我的代码和排查思路:
问题背景
最初发现Controller无法直接以数字类型处理输入值,参考方案修改了onChange逻辑:
<Controller // 去掉了rules里的valueAsNumber: true render={({ field }) => ( <input type="number" onChange={(event) => field.onChange(+event.target.value)} // 手动转数字 /> )} />
基于这个思路封装了NumberInput组件,但运行后报错Invalid Hook Call:
import React, { ChangeEvent } from 'react' import { Controller } from 'react-hook-form' import { getPlaceholder } from './getPlaceholder' import { IInput } from './types' const NumberInput: React.FC<IInput> = ({ control, name, ...props }) => { const placeholder = getPlaceholder({ type: "number" }); const numericalOnChange = (event: ChangeEvent<HTMLInputElement>) => { if (event.target.value === '') return null; return +event.target.value; } return ( <Controller control={control} name={name} render={({ field: { onChange, ...field } }) => ( <input {...props} {...field} type="number" placeholder={placeholder} onChange={(event) => { const value = numericalOnChange(event) onChange(value) }} className="h-[20px] pl-[4px] py-[8px] bg-transparent border-b border-b-[#646464] focus:border-b-[#3898EC] text-[13px] text-[#F00] placeholder-[#646464] outline-none m-1 w-full" /> )} /> ) } export default NumberInput
错误原因排查与解决
Invalid Hook Call错误通常是违反了React Hooks的使用规则,结合代码来看,最可能的问题点:
1. 检查getPlaceholder函数是否调用了React Hooks
如果getPlaceholder内部使用了useState、useEffect等Hook,但它本身不是自定义Hook(没有以use开头命名),也不是在React组件/自定义Hook的顶层调用,就会触发这个错误。
解决办法:
如果getPlaceholder依赖Hook逻辑,将其改为自定义Hook,遵循命名规则:
// 修改getPlaceholder为自定义Hook export function useGetPlaceholder(params: { type: string }) { // 原来的逻辑(如果有Hook调用,比如useState) // const [placeholder] = useState(...) // ... return placeholder; } // 在NumberInput中调用 const NumberInput: React.FC<IInput> = ({ control, name, ...props }) => { const placeholder = useGetPlaceholder({ type: "number" }); // 组件顶层调用自定义Hook // ... 其余代码不变 }
2. 确认父组件中control的传递是否正确
确保父组件里的control是通过useForm()正确获取的,且传递给NumberInput时没有错误:
import { useForm } from 'react-hook-form'; import NumberInput from './NumberInput'; function ParentComponent() { const { control } = useForm({ defaultValues: { // 确保默认值类型匹配,比如数字或null age: null } }); return <NumberInput control={control} name="age" />; }
3. 可选:简化onChange逻辑
可以去掉单独的numericalOnChange函数,直接内联处理,让代码更简洁:
onChange={(event) => { const inputValue = event.target.value; onChange(inputValue === '' ? null : +inputValue); }}
内容的提问来源于stack exchange,提问作者Noah -
相关产品推荐
相关产品推荐

