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

如何在React中使用react-hook-form条件处理动态下拉选择框选项

基于react-hook-form实现字段数组下拉选项动态过滤方案

实现思路

核心逻辑是实时收集所有同组字段已选中的下拉值,在渲染每个字段的下拉框时过滤掉其他字段已占用的选项,保证每个选项只能被选中一次,新增字段时自动展示剩余可用选项。

具体实现步骤

  • 先定义全局的原始下拉选项池,通过useForm初始化表单默认值,调用useFieldArray管理字段数组的增删操作
  • 使用watch监听整个字段数组的变化,实时提取所有已选中的下拉值组成已选集合
  • 渲染每个字段的下拉组件时,对原始选项做过滤:仅保留未被其他字段选中的选项,以及当前字段自身已选中的选项
  • 新增字段时直接调用append方法添加空值字段,下拉框会自动渲染当前剩余的可用选项,所有选项被选完时可禁用新增按钮避免无效操作

核心代码示例

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

// 原始下拉选项池,可根据业务调整
const originalOptions = [
  { value: "opt1", label: "选项1" },
  { value: "opt2", label: "选项2" },
  { value: "opt3", label: "选项3" },
  { value: "opt4", label: "选项4" }
];

function DynamicFieldForm() {
  const { control, watch } = useForm({
    defaultValues: {
      fieldList: [{ selectVal: "", inputVal: "" }]
    }
  });

  const { fields, append } = useFieldArray({
    control,
    name: "fieldList"
  });

  // 实时获取所有字段已选的下拉值
  const selectedValueSet = new Set(
    watch("fieldList").map(item => item.selectVal).filter(Boolean)
  );

  return (
    <div>
      {fields.map((field, index) => {
        // 过滤当前字段的可用选项
        const curAvailableOptions = originalOptions.filter(opt => 
          !selectedValueSet.has(opt.value) || opt.value === field.selectVal
        );

        return (
          <div key={field.id} style={{ margin: "8px 0" }}>
            <Controller
              control={control}
              name={`fieldList.${index}.selectVal`}
              render={({ field }) => (
                <select {...field} style={{ marginRight: "8px" }}>
                  <option value="">请选择</option>
                  {curAvailableOptions.map(opt => (
                    <option key={opt.value} value={opt.value}>
                      {opt.label}
                    </option>
                  ))}
                </select>
              )}
            />
            <Controller
              control={control}
              name={`fieldList.${index}.inputVal`}
              render={({ field }) => (
                <input {...field} placeholder="请输入补充内容" />
              )}
            />
          </div>
        );
      })}

      <button
        onClick={() => append({ selectVal: "", inputVal: "" })}
        disabled={selectedValueSet.size === originalOptions.length}
        style={{ marginTop: "12px" }}
      >
        新增字段
      </button>
    </div>
  );
}

优化提示

若选项数量较多,可以使用useMemo缓存selectedValueSet和每个字段的curAvailableOptions计算结果,减少重复计算开销,提升渲染性能。
如果业务允许同一个选项被多次选中,只需要调整过滤逻辑即可,不需要修改整体实现结构。

内容的提问来源于stack exchange,提问作者psilva.maf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:15:04