为何react-hook-form提交时判定select字段为空?
问题:提交时
category字段被判定为空,触发react-hook-form无效回调 提交表单时,category字段总是被判定为空,触发react-hook-form的无效回调,但明明已经选择了选项,相关简化代码如下:
import React from 'react'; import styled from 'styled-components'; import { useForm } from 'react-hook-form'; import * as yup from "yup"; import { yupResolver } from '@hookform/resolvers/yup'; const SelectRoot = styled.div` position: relative; `; export const SelectOriginal = styled.select` width: 100%; `; export function Select(props) { return ( <SelectRoot> <SelectOriginal {...props} /> </SelectRoot> ); } const schema = yup .object({ category: yup.string().required(), }) .required(); export default function App() { const { register, handleSubmit, } = useForm({ resolver: yupResolver(schema) }); const onValidSubmit = async (data) => { console.log('valid: ', data) } const onInvalidSubmit = async (errors) => { console.log('invalid: ', errors) } return ( <div> <form onSubmit={handleSubmit(onValidSubmit, onInvalidSubmit)}> <Select {...register('category')}> <option value="option-1">Option 1</option> <option value="option-2">Option 2</option> </Select> <button type="submit">Submit</button> </form> </div> ); }
原因与解决方案
原因
react-hook-form的register方法返回的对象包含ref属性,这个ref必须绑定到实际的表单DOM元素上,库才能正确读取表单值。你的自定义Select组件没有处理ref传递,导致register返回的ref无法绑定到内部的SelectOriginal(原生select元素),最终react-hook-form无法获取category的选中值,判定字段为空。
解决方案
用React.forwardRef包装自定义Select组件,将外部传入的ref转发给内部的原生select元素:
修改后的Select组件代码:
export const Select = React.forwardRef((props, ref) => { return ( <SelectRoot> <SelectOriginal ref={ref} {...props} /> </SelectRoot> ); });
修改后,register返回的ref会被正确绑定到原生select元素上,react-hook-form就能正常读取选中值,表单提交时不会再判定category为空。
内容的提问来源于stack exchange,提问作者Paulo R.
相关产品推荐
相关产品推荐

