You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Radix UI Select组件无法与React Hook Form Controller配合使用的问题求助

Radix UI Select与React Hook Form Controller配合问题排查与解决

我没法把Radix UI的Select组件和React Hook Form的Controller一起用,不知道自己写的示例代码为啥跑不起来,求解决思路。

Radix UI官方示例写法参考

官方文档里的写法是给SelectPrimitive.Root传递value和onChange属性,同时把ref传给SelectPrimitive.Trigger:

export const Select = React.forwardRef(
  ({ children, ...props }, forwardedRef) => {
    return (
      <SelectPrimitive.Root {...props}>
        <SelectPrimitive.Trigger ref={forwardedRef}>
          <SelectPrimitive.Value />
          {/* 其他组件内容 */}
        </SelectPrimitive.Trigger>
      </SelectPrimitive.Root>
    );
  }
);

我的实现代码

我封装的SelectItem组件:

const SelectItem = forwardRef(({ value, onValueChange }, forwardedRef) => {
  return (
    <Select.Root value={value} onValueChange={onValueChange}>
      <Select.Trigger
        ref={forwardedRef}
        className="text-md border-solid border-2 border-slate-500 px-2"
      >
        {/* 其他组件内容 */}
      </Select.Trigger>
    </Select.Root>
  );
});

我在WrapperSelect里用Controller的方式:

<Controller
  control={control}
  name={name}
  render={({ field: { onChange, value, ref, ...props } }) => (
    <SelectItem
      valueOnChange={onChange}
      value={value}
      forwardedRef={ref}
    />
  )}
/>

解决思路

  • 参数名不匹配:你在Controller里给SelectItem传的是valueOnChange,但组件定义里接收的是onValueChange,参数名错误导致表单onChange无法触发,值没法更新。
  • forwardRef传递错误:forwardRef需要通过组件的ref属性传递,而不是作为普通的forwardedRef props传,这样React Hook Form才能正确获取到组件的ref。
  • 值类型不匹配:确保React Hook Form表单字段的初始值、选中值和Radix UI Select的选项value类型完全一致(比如都是字符串或数字),否则会出现选中状态不生效的问题。

修正后的代码示例

修正Controller调用方式

<Controller
  control={control}
  name={name}
  render={({ field: { onChange, value, ref } }) => (
    <SelectItem
      onValueChange={onChange}
      value={value}
      ref={ref}
    />
  )}
/>

完整的SelectItem组件(补全必要部分)

import React from 'react';
import * as Select from '@radix-ui/react-select';

const SelectItem = React.forwardRef(({ value, onValueChange }, forwardedRef) => {
  return (
    <Select.Root value={value} onValueChange={onValueChange}>
      <Select.Trigger
        ref={forwardedRef}
        className="text-md border-solid border-2 border-slate-500 px-2 py-1 rounded"
      >
        <Select.Value placeholder="请选择选项" />
      </Select.Trigger>
      <Select.Portal>
        <Select.Content className="border border-slate-300 rounded-md">
          <Select.Item value="option1" className="px-3 py-2 hover:bg-slate-100">
            <Select.ItemText>选项1</Select.ItemText>
          </Select.Item>
          <Select.Item value="option2" className="px-3 py-2 hover:bg-slate-100">
            <Select.ItemText>选项2</Select.ItemText>
          </Select.Item>
        </Select.Content>
      </Select.Portal>
    </Select.Root>
  );
});

export default SelectItem;

额外注意事项

  • 确认已经完整安装并导入Radix UI Select的所有依赖组件
  • 检查React Hook Form的useForm初始化时,defaultValues里对应字段的初始值要和Select选项的value类型匹配

内容的提问来源于stack exchange,提问作者dumdum3000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:15:59