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

使用Controller结合自定义组件时,如何设置React Hook Form默认值

React Hook Form 受控组件默认值设置与Controller机制解析

一、解决自定义受控组件默认值不生效的方案

1. 推荐方式:在useForm初始化时配置defaultValues

直接在useForm初始化时传入全局默认值,React Hook Form会自动将这些值同步给所有关联的Controller组件,无需额外使用useEffect+reset:

import { useForm, Control } from "react-hook-form";

const RegistrationForm = () => {
  // 直接在useForm初始化时设置默认值
  const { control, register } = useForm({
    defaultValues: {
      standardRadio: "mint",
      registerRadio: "supercross"
    }
  });

  return (
    <div>
      {/* 自定义受控组件无需再传defaultValue */}
      <WrapperRadioGroup
        name="standardRadio"
        groupLabel="This is a radio group label"
        control={control}
        style="standard"
        options={[
          { value: "orange", label: "Orange ice cream" },
          { value: "mint", label: "Mint ice cream" },
          { value: "chocolate", label: "Chocolate ice cream" },
          { value: "vanilla", label: "Vanilla ice cream" }
        ]}
      />

      {/* 非受控组件保持原有写法即可 */}
      <input
        {...register("registerRadio")}
        id="registerRadio1"
        type="radio"
        value="motogp"
      />
      <label htmlFor="registerRadio1">Moto GP</label>
      {/* 其他单选框省略 */}
    </div>
  );
};

2. 确保自定义组件正确接收Controller的状态

你的WrapperRadioGroup必须通过Controller的render props接收表单状态的value和onChange方法,绑定到内部的单选框上,而不是自行设置defaultValue(受控组件的value由外部状态控制,defaultValue会被忽略)。正确的组件实现示例:

import { Controller, Control } from "react-hook-form";

type WrapperRadioGroupProps = {
  name: string;
  groupLabel: string;
  control: Control<any>;
  style: string;
  options: { value: string; label: string }[];
};

const WrapperRadioGroup = ({ name, groupLabel, control, options }: WrapperRadioGroupProps) => {
  return (
    <Controller
      name={name}
      control={control}
      render={({ field: { value, onChange } }) => (
        <div className={`radio-group-${style}`}>
          <h3>{groupLabel}</h3>
          {options.map((option) => (
            <div key={option.value} className="radio-item">
              <input
                type="radio"
                id={`${name}-${option.value}`}
                value={option.value}
                // 绑定Controller传递的value,判断是否选中
                checked={value === option.value}
                // 触发时调用Controller的onChange更新表单状态
                onChange={(e) => onChange(e.target.value)}
              />
              <label htmlFor={`${name}-${option.value}`}>{option.label}</label>
            </div>
          ))}
        </div>
      )}
    />
  );
};

二、Controller默认值的核心机制

  1. 默认值来源:Controller的默认值优先取自useForm初始化时的defaultValues对象,其次是调用reset方法传入的参数。这两个方式都会更新React Hook Form内部的表单状态,Controller会自动同步这个状态到受控组件。
  2. 受控组件的本质:Controller是React Hook Form和自定义受控组件的桥梁——它负责从表单状态中读取对应name的value,传递给组件;同时接收组件的 onChange 事件,将新值同步回表单状态。
  3. 常见坑点:给受控组件设置defaultValue是无效的,因为受控组件的value由外部状态(这里是React Hook Form的表单状态)完全控制,defaultValue只会在组件首次渲染时生效一次,但会被Controller传递的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.13 15:05:34