React Hook Form中fieldArray的setValue仅首次生效问题求助
React Hook Form fieldArray 调用setValue后UI不同步的解决方法
问题场景
初始将articles字段默认值设为[],首次调用setValue("articles", [{articleId: 1, price: 100, qte: 10 }])时,UI能正常同步;但手动修改输入框(比如把price改成120)后,再次调用setValue更新数组,React Hook Form内部状态已更新,UI却没跟着刷新。
原因分析
React Hook Form对fieldArray做了渲染优化,当用户手动修改过数组内的字段后,字段会被标记为touched状态,此时直接用setValue覆盖整个数组,无法触发fieldArray对应组件的重新渲染,导致UI不同步。
解决方案
方案1:使用fieldArray专属的replace方法(推荐)
React Hook Form的useFieldArray提供了replace方法,专门用于替换整个fieldArray,能正确触发UI刷新,无论数组是否被手动修改过。
代码示例:
import { useForm, useFieldArray } from "react-hook-form"; function App() { const { register, control, watch } = useForm({ defaultValues: { articles: [] } }); // 解构fieldArray的操作方法 const { fields, replace } = useFieldArray({ control, name: "articles" }); // 用replace替代setValue来更新数组 const updateArticles = (newArticles) => { replace(newArticles); }; return ( <div className="App"> {fields.map((item, index) => ( <div key={item.id}> <input {...register(`articles.${index}.articleId`)} type="number" placeholder="articleId" /> <input {...register(`articles.${index}.price`)} type="number" placeholder="price" /> <input {...register(`articles.${index}.qte`)} type="number" placeholder="qte" /> </div> ))} <button onClick={() => updateArticles([{articleId: 1, price: 100, qte: 10}])}> 设置初始值 </button> <button onClick={() => updateArticles([{articleId: 2, price: 200, qte: 20}])}> 更新数组 </button> <p>当前表单值: {JSON.stringify(watch("articles"))}</p> </div> ); } export default App;
方案2:给setValue添加强制更新配置
如果坚持要用setValue,可以在调用时传入配置参数,强制标记字段为dirty和touched,触发UI更新:
setValue("articles", newArticles, { shouldDirty: true, shouldTouch: true });
不过这种方式属于"绕过"RHf的优化逻辑,不如replace方法贴合fieldArray的设计规范,优先推荐方案1。
内容的提问来源于stack exchange,提问作者B. Fateh
相关产品推荐
相关产品推荐

