如何在Radix Primitives的Form组件中提交Select组件的值?
在Radix Primitives Form中结合Select组件提交到Next.js Server Action的正确方式
问题核心在于Radix Select是自定义UI组件,并非原生表单元素,无法自动将选中值注入FormData,可通过以下步骤解决:
实现步骤
- 借助Form.Field的render prop获取表单字段的状态与更新方法
- 将Select组件的选中值与Form字段状态双向绑定
- 添加隐藏的
Form.Input承载提交值,确保Server Action能读取到数据
完整代码示例:
import { Form } from '@radix-ui/react-form'; import { Select } from '@radix-ui/react-select'; // Server Action export const create = (formData: FormData) => { console.log(formData.get("gender")); // 现在可正确获取值 }; export default function GenderForm() { return ( <Form.Root action={create}> <Form.Field name="gender"> {(field) => ( <div> <Form.Label>Gender</Form.Label> <Form.Control asChild> <Select.Root value={field.value} onValueChange={field.setValue} > <Select.Trigger aria-label="选择性别"> <Select.Value placeholder="请选择性别" /> </Select.Trigger> <Select.Portal> <Select.Content> <Select.Item value="m">Male</Select.Item> <Select.Item value="f">Female</Select.Item> </Select.Content> </Select.Portal> </Select.Root> </Form.Control> {/* 隐藏输入框,用于将选中值注入FormData */} <Form.Input type="hidden" value={field.value} /> </div> )} </Form.Field> <Form.Submit>OK</Form.Submit> </Form.Root> ); }
关键说明
- 状态同步:通过
field.value和field.setValue将Select的选中状态与Form字段状态绑定,保证UI展示与表单数据一致。 - FormData注入:Radix Select不是原生表单控件,无法被表单自动收集值,隐藏的
Form.Input会在提交时将字段名和值传入FormData,让Server Action可通过formData.get("gender")获取选中值。 - Form.Control作用:包裹Select是为了继承表单的状态(如禁用、错误样式等),保证组件的无障碍特性与表单状态联动。
内容的提问来源于stack exchange,提问作者user3357926
相关产品推荐
相关产品推荐

