react-hook-form v7.6.1集成react-select校验错误无法自动聚焦问题咨询
问题根因
react-hook-form v7 重构了Controller组件的底层处理逻辑,和v6及更早版本相比有两个核心差异导致聚焦失效:
- v7 不再自动为自定义封装组件做focus逻辑适配,默认错误自动聚焦仅对原生表单元素生效
- react-select/creatable-react-select 属于封装组件,可聚焦的输入框隐藏在组件内部,根DOM节点不支持原生focus方法,必须调用组件实例暴露的
focus()方法才能触发聚焦,react-hook-form默认无法识别该方法
可行修复方案
有两种实现方式均可解决问题:
方案1:监听错误状态主动触发聚焦(最稳定)
通过useRef拿到creatable-react-select的组件实例,监听对应字段的错误状态,错误触发时主动调用实例的focus方法,代码示例如下:
import { useForm, Controller } from 'react-hook-form'; import CreatableSelect from 'creatable-react-select'; import { useEffect, useRef } from 'react'; const FormDemo = () => { const { control, handleSubmit, formState: { errors } } = useForm(); // 存储select组件实例 const selectRef = useRef(null); // 字段出错时自动聚焦 useEffect(() => { if (errors.selectField) { selectRef.current?.focus(); } }, [errors.selectField]); const submitHandler = (formData) => console.log(formData); return ( <form onSubmit={handleSubmit(submitHandler)}> <Controller name="selectField" control={control} rules={{ required: '该字段为必填项' }} render={({ field }) => ( <CreatableSelect {...field} ref={selectRef} // 绑定组件实例到ref options={[ { label: '选项A', value: 'a' }, { label: '选项B', value: 'b' } ]} /> )} /> <p>{errors.selectField?.message}</p> <button type="submit">提交</button> </form> ); };
方案2:提交错误回调中触发聚焦
如果不需要实时监听错误,仅需要在提交校验失败时聚焦,可直接在提交错误回调中处理,不需要额外useEffect监听:
const errorHandler = (formErrors) => { if (formErrors.selectField) { selectRef.current?.focus(); } }; // 表单提交处修改为 <form onSubmit={handleSubmit(submitHandler, errorHandler)}>
内容的提问来源于stack exchange,提问作者Sanath
相关产品推荐
相关产品推荐

