使用Shadcn UI Select实现Next.js Server Action时无法获取选中值
解决Shadcn UI Select配合Next.js Server Action无法传递选中值的问题
问题核心是Shadcn UI的Select组件基于Radix UI实现,属于自定义控件,并非原生<select>元素,因此表单提交时不会自动将选中值纳入FormData,导致服务端仅能获取到Server Action的标识,无法拿到实际选中值。
解决方案:添加隐藏输入框同步选中值
修改客户端UI代码,通过隐藏input将Select的选中值同步到表单数据中:
"use client"; import { Button } from "@/components/ui/button"; import * as React from "react"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Submit } from "@/lib/actions"; export default function Home() { // 存储选中值的状态 const [selectedFramework, setSelectedFramework] = React.useState(""); return ( <form action={Submit}> {/* 隐藏输入框,用于将选中值同步到FormData */} <input type="hidden" name="framework" value={selectedFramework} /> <div className="grid w-full items-center"> <div className="flex flex-col space-y-1.5"> <Label htmlFor="framework">Genre</Label> {/* 绑定Select的value和onValueChange,同步状态 */} <Select value={selectedFramework} onValueChange={setSelectedFramework}> <SelectTrigger id="framework"> <SelectValue placeholder="Select" /> </SelectTrigger> <SelectContent position="popper"> <SelectItem value="next">Next.js</SelectItem> <SelectItem value="sveltekit">SvelteKit</SelectItem> <SelectItem value="astro">Astro</SelectItem> <SelectItem value="nuxt">Nuxt.js</SelectItem> </SelectContent> </Select> </div> </div> <Button type="submit">Find</Button> </form> ); }
修改Server Action获取值
更新服务端代码,直接从FormData中提取字段值:
"use server"; export async function Submit(data: FormData) { // 获取选中的框架值 const framework = data.get("framework"); console.log("选中的框架:", framework); // 打印完整FormData验证 console.log("完整表单数据:", data); }
原理说明
自定义Select组件不会像原生<select>那样自动关联表单数据,通过添加隐藏input并将其value与Select的选中值绑定,表单提交时会自动将该值纳入FormData,服务端即可正常获取。
内容的提问来源于stack exchange,提问作者xMorlor
相关产品推荐
相关产品推荐

