使用React Hook Form的Controller组件时如何设置焦点?
解决React Hook Form Controller组件字段错误时自动聚焦问题
问题分析
你遇到的Property 'ref' does not exist on type 'IntrinsicAttributes'错误,是因为Controller组件本身不支持直接传入ref属性。要实现错误时自动聚焦,需要将ref关联到内部的TextField,并结合React Hook Form的表单状态监听来触发聚焦动作。
修正后的代码
import React, { useRef, useEffect } from "react"; import TextField from '@material-ui/core/TextField'; import { Control, Controller, useFormState } from "react-hook-form"; import { Keys } from '../Profile/interfaces'; interface Props { id: string; label: string; variant: "filled" | "standard" | "outlined"; disabled?: boolean; control: Control<any, any>; required?: boolean; name: Keys; requiredMsg?: string; } const CustomTextBox: React.FC<Props> = ({ id, label, variant, disabled = false, control, required = false, name, requiredMsg }) => { // 修正ref类型:TextField的输入框是HTMLInputElement,而非按钮元素 const inputRef = useRef<HTMLInputElement>(null); // 获取表单错误状态 const { errors } = useFormState({ control }); // 监听对应字段的错误,出现错误时自动聚焦 useEffect(() => { if (errors[name]) { inputRef.current?.focus(); } }, [errors, name]); return ( <Controller name={name} control={control} rules={{ required: required ? requiredMsg : null }} render={({ field }) => ( <TextField // 同时绑定表单注册ref和自定义聚焦ref,兼顾表单功能和手动聚焦需求 inputRef={(element) => { field.ref(element); inputRef.current = element; }} InputLabelProps={{ shrink: true }} id={id} label={label} variant={variant} disabled={disabled} {...field} style={{ marginTop: '10px', marginBottom: '10px', minWidth: '250px' }} /> )} /> ); }; export default CustomTextBox;
关键修改点说明
- 修正Ref类型:将错误的
HTMLButtonElement类型改为HTMLInputElement,匹配TextField输入框的真实元素类型。 - 监听错误状态:通过
useFormState获取表单错误对象,用useEffect监听目标字段的错误变化,一旦检测到错误就触发聚焦。 - 关联双Ref:在TextField的
inputRef回调中,同时绑定React Hook Form的字段注册ref和自定义聚焦ref,既保证表单字段能正常注册,又能手动控制输入框聚焦。
内容的提问来源于stack exchange,提问作者Lyle Phillips
相关产品推荐
相关产品推荐

