React-Hook-Form中map函数内条件字段的问题及解决
在React-Hook-Form的map循环中实现独立条件字段的问题与解决
问题场景
需要在React-Hook-Form的map循环中渲染带条件字段的列表项:每个项包含一个开关,开关开启时显示对应的输入框。初始实现后出现异常:切换任意一个开关,所有项的条件输入框都会同步显示/隐藏,且表单提交时无法区分不同项的字段值。
初始实现代码:
{goals && goals.map((goal) => ( <> <FormControlLabel control={ <Switch key={goal.title} {...register('marked')} name='marked' value={goal.marked} /> } label={goal.title} /> <br /> {marked && ( <> <Input key={goal.title} {...register('goal.note')} id="note" type='text' label="Progress Note" name="note" onChange={(e) => { e.target.value = e.target.value }} /> <br /> </> ) } </> ))}
问题根源
所有map生成的列表项共用同一个marked状态变量,导致UI联动逻辑错误;同时表单字段的name属性未区分不同项,提交时所有项的字段值会被覆盖,无法正确传递单个项的信息。
已实现的解决方案
通过拆分独立子组件,并利用循环索引管理每个项的独立状态,解决了UI联动问题:
父组件代码
{goals && goals.map((goal, index) => ( <GoalInput goal={goal} index={index} register={register} control={control} errors={errors} /> ))}
子组件代码
function GoalInput({ goal, index, register, control, errors }) { const [toggle, setToggle] = useState(false) return ( <> <FormControlLabel control={ <Switch key={index} {...register(`goals.${index}.marked`)} checked={toggle} name={`goals.${index}.marked`} value={toggle} onChange={() => setToggle(!toggle)} /> } label={goal.title} /> <br /> {toggle ? ( <> <Controller control={control} name={`goals.${index}.note`} id={`goals.${index}.note`} render={({field}) => ( <Input type='text' index={index} error={!!errors.note} value={field.value} onChange={(e)=>field.onChange(e)} label="Progress Note" /> )} /> <br /> </> ) : <></>} </> ) }
目前开关可独立切换,条件输入框的状态能正确追踪,但仍存在后端数据传递的小问题。
内容的提问来源于stack exchange,提问作者Jowz
相关产品推荐
相关产品推荐

