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

React Select初始渲染无法显示props传入的默认分类ID问题求助

问题

开发了一个可复用的下拉选择组件RHFSelect,用于项目新增与编辑场景:

  • 新增项目时可正常设置分类;
  • 编辑项目时,虽已将项目所属分类的_id通过categoryID props传入组件,但下拉框初始渲染时无法显示选中的分类,后续渲染才会正常显示。

组件代码

export default function RHFSelect({
  label,
  name,
  register,
  options,
  required,
  validationschema,
  errors,
  categoryID = "",
}) {
  return (
    <div>
      <select
        className="textField__input"
        {...register(name, validationschema)}
        id={name}
        defaultValue={categoryID}
      >
        <option value="">Please select the project category</option>

        {options.map((option) => {
          return (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          );
        })}
      </select>
      {errors && errors[name] && (
        <span className="text-error block text-sm mt-2">
          {errors[name]?.message}
        </span>
      )}
    </div>
  );
}

补充说明

  • options为从数据库获取的分类列表;
  • categoryID默认值为空字符串,编辑模式下传入对应分类ID;
  • 期望新增模式显示“Please select the project category”,编辑模式默认显示之前选中的分类。

解决方案

问题核心:React Hook Form的register方法会接管表单控件的值管理,直接设置defaultValue在异步场景(比如options从数据库加载)下会失效——初始渲染时options可能未获取完成,或者register的状态初始化逻辑覆盖了defaultValue。

方式一:使用React Hook Form的defaultValues配置(推荐)

在表单初始化时通过useForm的defaultValues设置对应字段默认值,而非在组件内用defaultValue:

// 父组件中初始化useForm
const { register, errors } = useForm({
  defaultValues: {
    // 编辑模式传入categoryID,新增模式为空
    category: categoryID || ""
  }
});

// 修改后的RHFSelect组件
export default function RHFSelect({
  label,
  name,
  register,
  options,
  required,
  validationschema,
  errors,
}) {
  return (
    <div>
      <select
        className="textField__input"
        {...register(name, validationschema)}
        id={name}
      >
        <option value="">Please select the project category</option>
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
      {errors && errors[name] && (
        <span className="text-error block text-sm mt-2">
          {errors[name]?.message}
        </span>
      )}
    </div>
  );
}

方式二:使用useController替代register(适合组件内控制默认值场景)

如果需要在组件内部处理默认值,用useController接管控件,确保初始值同步:

import { useController } from "react-hook-form";

export default function RHFSelect({
  label,
  name,
  control,
  options,
  required,
  validationschema,
  errors,
  categoryID = "",
}) {
  const { field } = useController({
    control,
    name,
    rules: validationschema,
    defaultValue: categoryID,
  });

  return (
    <div>
      <select
        className="textField__input"
        {...field}
        id={name}
      >
        <option value="">Please select the project category</option>
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
      {errors && errors[name] && (
        <span className="text-error block text-sm mt-2">
          {errors[name]?.message}
        </span>
      )}
    </div>
  );
}

// 父组件传入control
const { control, errors } = useForm();
<RHFSelect control={control} name="category" categoryID={categoryID} options={options} />

关键注意点

  1. React Hook Form的register会优先使用useForm初始化时的defaultValues,而非控件自身的defaultValue,异步加载数据场景下,要确保defaultValues在数据就绪后初始化表单,或用reset方法更新默认值。
  2. 如果options是异步获取的,需确保options加载完成后再渲染组件,或添加加载状态,避免初始渲染时无对应选项导致选中值无法显示。

内容的提问来源于stack exchange,提问作者Yahya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:14:54