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

React Hook Form 校验字段数组不同索引多字段值唯一性

React Hook Form 数组字段重复值校验方案

优先实现:字段级实时校验(提交前自动触发)

你原来的validate逻辑写法有误,不需要传当前值v给getValues,直接在校验函数里拉取整个documents数组做重复判断即可,修改后的代码如下:

<Select
  {...register(`documents.${index}.language`, {
    validate: (currentLang) => {
      // 获取整个文档数组的所有值
      const allDocs = getValues('documents') || [];
      // 提取所有已填写的语言值,过滤空项
      const allSelectedLangs = allDocs.map(item => item?.language).filter(Boolean);
      // 统计当前语言出现次数,超过1即为重复
      const isDuplicate = allSelectedLangs.filter(lang => lang === currentLang).length > 1;
      return !isDuplicate || '语言选项不能重复';
    }
  })}
  sx={{ textAlign: 'center' }}
>
  {availableLanguages
    ?.sort((a) => (a.name === 'pl' ? -1 : 1))
    // 排序将波兰语设为默认首选项
    .map((language) => (
      <option key={language.name} value={language.name}>
        {language.name.toUpperCase()}
      </option>
    ))}
</Select>

这个方案的特点:

  • 单个字段值修改、数组增删条目时都会自动触发校验,用户在填写过程中就能看到重复提示,不用等到点击提交按钮
  • 校验逻辑完全接入React Hook Form的原生校验流,错误信息可以直接通过formState.errors.documents获取渲染,不需要额外维护错误状态

备选实现:提交阶段全局校验

如果你需要在提交时统一做校验,可以在提交回调里加去重判断,逻辑更简单:

const onSubmit = (formData) => {
  const selectedLangs = formData.documents.map(item => item.language).filter(Boolean);
  // 利用Set去重后长度和原数组对比,判断是否有重复
  const hasDuplicateLang = new Set(selectedLangs).size !== selectedLangs.length;
  
  if (hasDuplicateLang) {
    // 可以通过setError手动挂载表单错误
    setError('documents.root', {
      type: 'duplicate',
      message: '所有文档的语言选项不能重复'
    });
    return;
  }

  // 校验通过后执行后续提交逻辑
}

提示:如果你的documents是动态增减的数组,优先选第一种字段级校验方案,不需要手动触发校验重跑,体验更流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:03:28