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

