react-hook-form Controller与ShadeCn Select组件问题:选中后值重置为空
问题:React Hook Form结合Select组件时的表单值异常与显示问题
问题现象
- 初始表单提交:未交互Select组件时,默认值可正常提交,符合预期。
- 选择后异常:交互Select组件(如
propertyType)并选择选项后,该字段提交数据变为空字符串;同时SelectTrigger始终显示占位文本,无法展示默认值或选中项。
原代码
"use client"; import { useForm, Controller } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form"; const formSchema = z.object({ location: z.string().min(1, "Location is required"), propertyType: z.string(), purpose: z.string(), priceRange: z.string(), beds: z.string(), filters: z.string(), }); const propertyTypeOptions = [ { value: "residential", label: "All in Residential" }, // Add more options as needed ]; export default function PropertyFilter() { const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { location: "", propertyType: propertyTypeOptions[0].value, purpose: "rent", priceRange: "any", beds: "any", filters: "baths-area", }, }); function onSubmit(values) { console.log(values); } return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="form-container"> <FormField control={form.control} name="propertyType" render={({ field }) => ( <FormItem> <FormLabel>Property Type</FormLabel> <FormControl> <Controller name="propertyType" control={form.control} render={({ field }) => ( <Select onValueChange={field.onChange} value={field.value} > <SelectTrigger> <SelectValue placeholder="Select a property type" /> </SelectTrigger> <SelectContent> {propertyTypeOptions.map((option) => ( <SelectItem key={option.value} value={option.value}> {option.label} </SelectItem> ))} </SelectContent> </Select> )} /> </FormControl> <FormMessage /> </FormItem> )} /> <button type="submit">Submit</button> </form> </Form> ); }
期望与实际行为
- 期望:SelectTrigger正确显示选中项或默认值;提交数据包含Select组件选择后的正确值。
- 实际:SelectTrigger初始无文本;选择选项后,对应字段提交值为空字符串。
问题根源与修复方案
原代码核心问题是同时嵌套使用FormField和Controller——FormField内部已经封装了Controller的字段管理逻辑,重复嵌套会导致字段状态冲突,覆盖值的更新逻辑,最终引发显示和提交异常。
Select组件修复代码
移除外层的FormField,直接使用Controller与Select组件结合:
<FormItem> <FormLabel>Property Type</FormLabel> <FormControl> <Controller name="propertyType" control={form.control} render={({ field }) => ( <Select onValueChange={field.onChange} value={field.value} > <SelectTrigger> <SelectValue placeholder="Select a property type" /> </SelectTrigger> <SelectContent> {propertyTypeOptions.map((option) => ( <SelectItem key={option.value} value={option.value}> {option.label} </SelectItem> ))} </SelectContent> </Select> )} /> </FormControl> <FormMessage /> </FormItem>
关于你提供的InputFieldForm组件
该组件是针对Input输入框的封装,逻辑正确——核心是单独使用Controller处理字段,避免与FormField重复嵌套,可直接用于普通输入框的表单管理。
内容的提问来源于stack exchange,提问作者Yazan
相关产品推荐
相关产品推荐

