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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:17:03