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

React Hook Form添加空值异常:重复点击添加按钮仅生效一次

React Hook Form useFieldArray连续append空值无效的原因及解决方法

问题原因

React Hook Form的useFieldArray在执行append操作时,会对新增值和数组现有值做浅比较。当你连续append空字符串时,第一次append后数组变为['football', ''],第二次append的空字符串和数组最后一项的空值浅比较结果相等,React Hook Form会判定表单状态没有实质变更,因此不会触发数组更新和组件重新渲染,导致第二次点击添加按钮无效果。

解决方法

核心思路是让每次append的内容都是唯一值,确保React Hook Form能检测到数组变化。这里提供两种可行方案:

方案1:append带唯一标识的对象

将空值包装成对象,利用对象引用的唯一性触发状态更新,后续提交时再提取有效内容:

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

const App = () => {
  const { register, control, handleSubmit } = useForm({
    defaultValues: { interests: [{ value: 'football' }] }
  });
  const { fields, append } = useFieldArray({
    control,
    name: "interests"
  });

  const addInterest = () => {
    append({ value: '' }); // 每次append新对象,引用唯一
  };

  const onSubmit = (data) => {
    // 处理成纯字符串数组,过滤空值
    const finalInterests = data.interests
      .map(item => item.value.trim())
      .filter(Boolean);
    console.log(finalInterests);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((item, index) => (
        <input
          key={item.id}
          {...register(`interests.${index}.value`)}
          placeholder="输入兴趣"
        />
      ))}
      <button type="button" onClick={addInterest}>添加兴趣</button>
      <button type="submit">提交</button>
    </form>
  );
};

export default App;

方案2:append带临时唯一后缀的字符串

通过给空字符串添加唯一后缀(如时间戳)确保每次新增值唯一,输入时再替换为用户输入内容:

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

const App = () => {
  const { register, control, handleSubmit, setValue } = useForm({
    defaultValues: { interests: ['football'] }
  });
  const { fields, append } = useFieldArray({
    control,
    name: "interests"
  });

  const addInterest = () => {
    // 用时间戳生成唯一临时值
    append(`__temp_${Date.now()}`);
  };

  const handleInputChange = (index, e) => {
    // 输入时替换掉临时值
    setValue(`interests.${index}`, e.target.value);
  };

  const onSubmit = (data) => {
    const finalInterests = data.interests
      .map(item => item.replace(/^__temp_\d+/, '').trim())
      .filter(Boolean);
    console.log(finalInterests);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((item, index) => (
        <input
          key={item.id}
          {...register(`interests.${index}`)}
          placeholder="输入兴趣"
          onChange={(e) => handleInputChange(index, e)}
        />
      ))}
      <button type="button" onClick={addInterest}>添加兴趣</button>
      <button type="submit">提交</button>
    </form>
  );
};

export default App;

总结

两种方案都能解决连续append空值无效的问题,推荐方案1,因为它的逻辑更清晰,不需要额外处理临时值,更符合React Hook Form的表单状态管理设计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:43:07