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

react-hook-form useFieldArray更新数组元素值问题求助

React Hook Form useFieldArray:setValue后fields值不同步的解决办法

问题原因

useFieldArray返回的fields是基于表单状态的快照值,仅会在调用它自身提供的方法(如update/push/remove)时更新。而form.setValue是直接修改表单底层状态,不会同步更新useFieldArray内部维护的fields状态,这就导致fields[0].data还停留在旧值,但watch/getValues能拿到最新值。

解决方案

方案1:用watch获取实时数组值(无需修改更新方式)

如果坚持用setValue更新,可通过watch监听整个数组,获取实时同步的字段值,代替直接使用fields里的快照数据:

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

function YourForm() {
  const { register, control, setValue, watch } = useForm({
    defaultValues: {
      array: [
        { name: "one", data: "long string" },
        { name: "two", data: "another long string" },
      ],
    },
  });
  const { fields } = useFieldArray({ control, name: "array" });
  // 监听数组,获取实时更新的版本
  const realtimeArray = watch("array");

  const updateFirstData = () => {
    setValue("array.0.data", "new updated string");
  };

  return (
    <div>
      <button onClick={updateFirstData}>更新第一个元素的data</button>
      {fields.map((field, index) => (
        <div key={field.id}>
          <input {...register(`array.${index}.name`)} />
          {/* 使用watch返回的实时值 */}
          <input 
            {...register(`array.${index}.data`)} 
            value={realtimeArray[index].data} 
          />
          <p>当前data值:{realtimeArray[index].data}</p>
        </div>
      ))}
    </div>
  );
}

方案2:使用useFieldArray的update方法(规范且无不必要重挂载)

你担心update会触发重新挂载其实是误解——只要渲染数组元素时使用field.id作为key,update仅会更新对应字段的值,不会触发组件重新挂载,同时还能保证fields和表单状态完全同步:

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

function YourForm() {
  const { register, control } = useForm({
    defaultValues: {
      array: [
        { name: "one", data: "long string" },
        { name: "two", data: "another long string" },
      ],
    },
  });
  const { fields, update } = useFieldArray({ control, name: "array" });

  const updateFirstData = () => {
    // 直接更新索引0的元素的data字段
    update(0, { data: "new updated string" });
  };

  return (
    <div>
      <button onClick={updateFirstData}>更新第一个元素的data</button>
      {fields.map((field, index) => (
        <div key={field.id}>
          <input {...register(`array.${index}.name`)} />
          <input {...register(`array.${index}.data`)} value={field.data} />
          <p>当前data值:{field.data}</p>
        </div>
      ))}
    </div>
  );
}

总结

  • 若必须用setValue,依赖watch的实时值即可解决同步问题;
  • 优先推荐useFieldArray的update方法,这是官方设计的数组字段更新方式,既保证状态同步,也不会触发不必要的组件重挂载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:43:00