如何实现React Hook Form与Radix UI Select的集成(Styled Components环境)
Radix UI Select 与 React Hook Form 集成方案
直接在S.Root上使用register无效的核心原因是:Radix UI Select 属于自定义组件,并非原生表单控件,React Hook Form 的register方法仅适配<input>、<select>这类符合原生表单规范的元素。要完成集成,必须用 React Hook Form 提供的Controller组件做桥接。
具体实现步骤
- 导入依赖
确保已经导入Controller和useForm的核心方法:
import { useForm, Controller } from 'react-hook-form';
- 重构 Select 组件结构
用Controller包裹 Radix Select 的根组件,通过render函数拿到表单控制所需的field对象(包含value、onChange),将其绑定到 Radix Select 的对应属性上:
<S.FormItem key={index}> <S.Label htmlFor={index+''}>{question.question}</S.Label> <Controller name={questionName} control={control} // 来自useForm返回的control对象 rules={{ required: true }} // 验证规则 render={({ field }) => ( <S.Root value={field.value} onValueChange={field.onChange} > <S.Trigger id={index+''}> {/* 给S.Value绑定当前选中值,确保选中后显示正常 */} <S.Value value={field.value} /> <S.Icon> <S.TriggerIcon src="/form/selector-icon.svg" /> </S.Icon> </S.Trigger> <S.Portal> <S.Content> <S.SelectorUp>Up</S.SelectorUp> <S.Viewport> {question.options?.map((option, i) => ( <SelectItem key={i} value={option}> {option} </SelectItem> ))} </S.Viewport> <S.SelectorDown>Down</S.SelectorDown> </S.Content> </S.Portal> </S.Root> )} /> {/* 可选:添加必填错误提示 */} {errors[questionName] && <span style={{color: '#ef4444'}}>此字段为必填项</span>} </S.FormItem>
- 关键细节说明
Controller的name属性要和你原本用register时的questionName完全一致,保证表单值能正确存入 React Hook Form 的状态。S.Root的onValueChange会在选中项切换时触发,自动把选中值同步到表单状态;value属性绑定当前表单值,让组件处于受控状态。S.Value必须显式绑定value,否则选中选项后无法正确展示选中内容。
表单初始化上下文示例
确保你的表单初始化代码中,control对象正确传递给Controller:
const { control, handleSubmit, formState: { errors } } = useForm(); const onSubmit = (formData) => { console.log(formData); // 可获取Select选中的value };
内容的提问来源于stack exchange,提问作者Pedro Brandão
相关产品推荐
相关产品推荐

