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
相关产品推荐
相关产品推荐

